Bagaimana mendefinisikan kelas pengecualian kustom di Jawa, cara termudah?

286

Saya mencoba mendefinisikan kelas pengecualian saya sendiri dengan cara termudah, dan inilah yang saya dapatkan:

public class MyException extends Exception {}

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

Inilah yang dikatakan kompiler Java:

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

Saya merasa bahwa konstruktor ini harus diwarisi java.lang.Exception, bukan?

yegor256
sumber

Jawaban:

402

Tidak, Anda tidak "mewarisi" konstruktor non-default, Anda perlu mendefinisikan yang mengambil String di kelas Anda. Biasanya Anda gunakan super(message)di konstruktor untuk memohon konstruktor induk Anda. Misalnya, seperti ini:

public class MyException extends Exception {
    public MyException(String message) {
        super(message);
    }
}
djna
sumber
58
@vulkanino: Tidak. Konstruktor default ditambahkan oleh kompiler untuk setiap kelas yang tidak mendefinisikan konstruktor sendiri. Jika Anda mendefinisikan konstruktor eksplisit, Anda tidak mendapatkan default bahkan jika superclass memilikinya, dan jika kelas Anda tidak memiliki konstruktor, Anda mendapatkan default bahkan jika superclass tidak memilikinya.
Michael Borgwardt
5
if your class has no constructor, you get the default even if the superclass does not have itBagian terakhir tidak mungkin, kecuali superclass memiliki konstruktor default yang dapat diakses ke kelas ini (mungkin dilindungi atau dilindungi paket). Kalau tidak, Anda harus secara eksplisit memanggil salah satu konstruktor induk, atau kompilasi akan gagal.
Sean Patrick Floyd
43
Silakan tambahkan MyException(Throwable)dan MyException(String, Throwable)konstruktor untuk mendukung chaining pengecualian dengan benar .
Danilo Piazzalunga
8
Hampir 3 tahun kemudian dan tidak ada konstruktor tambahan yang ditambahkan. :(
byxor
2
@BrandonIbbotson Apa yang Anda maksud dengan 'mereka', dan di mana mereka ditambahkan? Jika apa yang Anda maksud dengan 'mereka' adalah pembangun superclass dan dengan 'where' adalah subclass, maka Anda salah. Konstruktor superclass tidak secara implisit ditambahkan ke subclass. Ditambah lagi, saya tidak bisa melihat subjek lain dalam kalimat sebelumnya untuk merujuk kata-kata itu.
Halil
90

Pengecualian khusus yang saya tentukan adalah sesuatu seperti ini:

public class CustomException extends Exception {

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

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

}

Saya bahkan membuat template menggunakan Eclipse jadi saya tidak perlu menulis semua hal berulang kali.

nanda
sumber
17
Anda bisa memperpanjang Exception saat membuat Kelas di Eclipse dan Anda akan mendapatkan keempat konstruktor. Anda tidak perlu templat.
jeremyjjbrown
Kapan kita harus menggunakan Consutructor yang kedua daripada yang pertama?
ZhaoGang
61

Jika Anda menggunakan dialog kelas baru di Eclipse Anda bisa mengatur bidang Superclass ke java.lang.Exceptiondan centang "Konstruktor dari superclass" dan itu akan menghasilkan yang berikut:

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
    }

}

Menanggapi pertanyaan di bawah ini tentang tidak memanggil super()konstruktor defualt, Oracle mengatakan ini :

Catatan: Jika konstruktor tidak secara eksplisit memanggil konstruktor superclass, kompiler Java secara otomatis memasukkan panggilan ke konstruktor no-argumen superclass.

Kevin Brey
sumber
22

Alasan untuk ini dijelaskan dalam artikel Warisan dari Platform Java yang mengatakan:

"Sebuah subclass mewarisi semua anggota (bidang, metode, dan kelas bertingkat) dari superclass-nya. Konstruktor bukan anggota , sehingga mereka tidak diwarisi oleh subclass, tetapi konstruktor dari superclass dapat dipanggil dari subclass."

Isaq
sumber
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());
        }
    }
}
Deepak Pakhale
sumber
apa yang akan kembali ini?
user1876508
Itu hanya akan mencetak "Halo Kembali Lagi dengan pengecualian kustom" yang berasal dari konstruktor untuk UseCusomException, pengecualian akan dibuang kemudian tertangkap di utama yang akan mencetak "Ini adalah pengecualian kustom saya: Ini adalah pengecualian kustom".
ThePerson
2

Kelas pengecualian memiliki dua konstruktor

  • public Exception() - Ini membangun Pengecualian tanpa informasi tambahan. Sifat pengecualian biasanya disimpulkan dari nama kelas.
  • public Exception(String s) - Membangun pengecualian dengan pesan kesalahan yang ditentukan. Pesan detail adalah String yang menggambarkan kondisi kesalahan untuk pengecualian khusus ini.
Deepak Pakhale
sumber
3
Sebenarnya, sejak Java 1.4, ada dua konstruktor lagi: public Exception(Throwable)dan public Exception(String, Throwable). Mereka diperlukan untuk mendukung dengan benar rantai pengecualian .
Danilo Piazzalunga
@DaniloPiazzalunga setuju dengan Anda. sumber: Constructor Summary docs.oracle.com/javase/1.5.0/docs/api/java/lang/Exception.html
KNU
0

Jika Anda mewarisi dari Pengecualian, Anda harus menyediakan konstruktor yang menggunakan String sebagai parameter (itu akan berisi pesan kesalahan).

vulkanino
sumber
Saya pikir Anda harus menambahkan alasan juga.
Jigar Joshi
3
sebenarnya, itu tidak benar. Jika kode Anda menggunakan konstruktor dengan satu argumen String, maka Anda harus mendeklarasikannya. Namun, subkelas Pengecualian dapat didefinisikan tanpa konstruktor eksplisit ... karena Pengecualian memiliki konstruktor tanpa argumen.
Stephen C
0

dan jangan lupa cara termudah untuk melempar pengecualian (Anda tidak perlu membuat kelas)

if (rgb > MAX) throw new RuntimeException("max color exceeded");
Lorne K
sumber