Làm thế nào để xác định lớp ngoại lệ tùy chỉnh trong Java, cách dễ nhất?


286

Tôi đang cố gắng xác định lớp ngoại lệ của riêng mình theo cách dễ nhất và đây là những gì tôi nhận được:

public class MyException extends Exception {}

public class Foo {
  public bar() throws MyException {
    throw new MyException("try again please");
  }
}

Đây là những gì trình biên dịch Java nói:

cannot find symbol: constructor MyException(java.lang.String)

Tôi có cảm giác rằng nhà xây dựng này phải được thừa hưởng từ java.lang.Exception, phải không?

Câu trả lời:


402

Không, bạn không "kế thừa" các hàm tạo không mặc định, bạn cần xác định chuỗi lấy chuỗi trong lớp của mình. Thông thường bạn sử dụng super(message)trong hàm tạo của bạn để gọi hàm tạo của cha mẹ. Ví dụ, như thế này:

public class MyException extends Exception {
    public MyException(String message) {
        super(message);
    }
}

58
@vulkanino: Không. Trình xây dựng mặc định được trình biên dịch thêm vào cho mỗi lớp xác định không có hàm tạo nào của chính nó. Nếu bạn xác định một hàm tạo rõ ràng, bạn sẽ không nhận được mặc định ngay cả khi siêu lớp có nó và nếu lớp của bạn không có hàm tạo, bạn sẽ có được mặc định ngay cả khi siêu lớp không có nó.
Michael Borgwardt

5
if your class has no constructor, you get the default even if the superclass does not have itPhần cuối cùng là không thể, trừ khi siêu lớp có một hàm tạo mặc định có thể truy cập được đối với lớp này (có thể được bảo vệ hoặc bảo vệ gói). Nếu không, bạn phải gọi một trong các hàm tạo cha mẹ, hoặc quá trình biên dịch sẽ thất bại.
Sean Patrick Floyd

43
Vui lòng thêm MyException(Throwable)và các nhà MyException(String, Throwable)xây dựng để hỗ trợ đúng cách ngoại lệ chuỗi .
Danilo Piazzalunga

8
Gần 3 năm sau và không có nhà xây dựng bổ sung nào được thêm vào. :(
byxor

2
@BrandonIbbotson Ý của bạn là 'họ' và họ được thêm vào đâu? Nếu ý của bạn là 'họ' là các nhà xây dựng siêu lớp và 'nơi' là lớp con, thì bạn đã nhầm. Các constructor của siêu lớp không được thêm vào lớp con. Ngoài ra, tôi không thể thấy bất kỳ chủ đề nào khác trong các câu trước để những từ đó tham khảo.
halil

90

Một ngoại lệ tùy chỉnh điển hình mà tôi xác định là một cái gì đó như thế này:

public class CustomException extends Exception {

    public CustomException(String message) {
        super(message);
    }

    public CustomException(String message, Throwable throwable) {
        super(message, throwable);
    }

}

Tôi thậm chí còn tạo một mẫu bằng cách sử dụng Eclipse vì vậy tôi không phải viết đi viết lại nhiều lần.


17
Bạn chỉ có thể mở rộng Ngoại lệ khi tạo Lớp của bạn trong Eclipse và bạn sẽ nhận được tất cả bốn hàm tạo. Bạn không cần một mẫu.
jeremyjjbrown

Khi nào chúng ta nên sử dụng Consutructor thứ hai thay vì cái thứ nhất?
ZhaoGang

61

Nếu bạn sử dụng hộp thoại lớp mới trong Eclipse, bạn có thể chỉ cần đặt trường java.lang.ExceptionSiêu lớp thành và kiểm tra "Trình xây dựng từ siêu lớp" và nó sẽ tạo ra như sau:

package com.example.exception;

public class MyException extends Exception {

    public MyException() {
        // TODO Auto-generated constructor stub
    }

    public MyException(String message) {
        super(message);
        // TODO Auto-generated constructor stub
    }

    public MyException(Throwable cause) {
        super(cause);
        // TODO Auto-generated constructor stub
    }

    public MyException(String message, Throwable cause) {
        super(message, cause);
        // TODO Auto-generated constructor stub
    }

}

Để trả lời cho câu hỏi dưới đây về việc không gọi super()hàm tạo của defualt, Oracle có điều này để nói :

Lưu ý: Nếu một hàm tạo không gọi một hàm tạo siêu lớp một cách rõ ràng, trình biên dịch Java sẽ tự động chèn một cuộc gọi đến hàm tạo không có đối số của siêu lớp.


1
Tại sao không cần thiết cho hàm tạo mặc định để gọi super()?
ceving


22

Lý do cho điều này được giải thích trong bài viết Kế thừa của Nền tảng Java có nội dung:

"Một lớp con kế thừa tất cả các thành viên (các trường, các phương thức và các lớp lồng nhau) từ siêu lớp của nó. Các hàm tạo không phải là thành viên , vì vậy chúng không được kế thừa bởi các lớp con, nhưng hàm tạo của lớp cha có thể được gọi từ lớp con."


19
package customExceptions;

public class MyException extends Exception{

    public MyException(String exc)
    {
        super(exc);
    }
    public String getMessage()
    {
        return super.getMessage();
    }
}

import customExceptions.MyException;

public class UseCustomException {

    MyException newExc=new MyException("This is a custom exception");

    public UseCustomException() throws MyException
    {
        System.out.println("Hello Back Again with custom exception");
        throw newExc;       
}

    public static void main(String args[])
    {
        try
        {
            UseCustomException use=new UseCustomException();
        }
        catch(MyException myEx)
        {
            System.out.println("This is my custom exception:" + myEx.getMessage());
        }
    }
}

Điều này sẽ trở lại?
dùng1876508

Nó sẽ chỉ in ra "Xin chào trở lại lần nữa với ngoại lệ tùy chỉnh", từ nhà xây dựng cho UseCusomException, ngoại lệ sẽ được ném ra sau đó được in ra chính "Đây là ngoại lệ tùy chỉnh của tôi: Đây là ngoại lệ tùy chỉnh".
ThePerson

2

Lớp ngoại lệ có hai hàm tạo

  • public Exception() - Điều này xây dựng một Ngoại lệ mà không có bất kỳ thông tin bổ sung nào. Ngoại lệ của ngoại lệ thường được suy ra từ tên lớp.
  • public Exception(String s) - Xây dựng một ngoại lệ với thông báo lỗi được chỉ định. Thông báo chi tiết là Chuỗi mô tả điều kiện lỗi cho ngoại lệ cụ thể này.

3
Trên thực tế, kể từ Java 1.4, có thêm hai hàm tạo: public Exception(Throwable)public Exception(String, Throwable). Chúng là cần thiết để hỗ trợ đúng cách ngoại lệ chuỗi .
Danilo Piazzalunga

@DaniloPiazzalunga đồng ý với bạn. nguồn: Trình xây dựng Tóm tắt docs.oracle.com/javase/1.5.0/docs/api/java/lang/Exception.html
KNU

0

Nếu bạn kế thừa từ Ngoại lệ, bạn phải cung cấp hàm tạo lấy Chuỗi làm tham số (nó sẽ chứa thông báo lỗi).


Tôi nghĩ bạn cũng nên thêm lý do.
Jigar Joshi

3
Thật ra, điều đó không chính xác. Nếu mã của bạn sử dụng một hàm tạo với một đối số Chuỗi, thì bạn phải khai báo nó. Tuy nhiên, một lớp con Exception có thể được định nghĩa mà không có hàm tạo rõ ràng ... bởi vì Exception có hàm tạo không có đối số.
Stephen C

0

và đừng quên cách dễ nhất để đưa ra một ngoại lệ (bạn không cần tạo một lớp)

if (rgb > MAX) throw new RuntimeException("max color exceeded");
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.