¿Cómo definir una clase de excepción personalizada en Java, la forma más fácil?

286

Estoy tratando de definir mi propia clase de excepción de la manera más fácil, y esto es lo que estoy obteniendo:

public class MyException extends Exception {}

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

Esto es lo que dice el compilador de Java:

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

Tenía la sensación de que este constructor tiene que ser heredado java.lang.Exception, ¿no?

yegor256
fuente

Respuestas:

402

No, no "heredas" constructores no predeterminados, debes definir el que toma una Cadena en tu clase. Por lo general, utiliza super(message)en su constructor para invocar a su constructor principal. Por ejemplo, así:

public class MyException extends Exception {
    public MyException(String message) {
        super(message);
    }
}
djna
fuente
58
@vulkanino: No. El compilador agrega el constructor predeterminado para cada clase que no define ningún constructor propio. Si define un constructor explícito, no obtiene el valor predeterminado incluso si la superclase lo tiene, y si su clase no tiene constructor, obtiene el valor predeterminado incluso si la superclase no lo tiene.
Michael Borgwardt
55
if your class has no constructor, you get the default even if the superclass does not have itLa última parte es imposible, a menos que la superclase tenga un constructor predeterminado que sea accesible para esta clase (puede estar protegido o protegido por paquete). De lo contrario, debe llamar explícitamente a uno de los constructores principales, o la compilación fallará.
Sean Patrick Floyd el
43
Agregue los constructores MyException(Throwable)y MyException(String, Throwable)para admitir correctamente el encadenamiento de excepciones .
Danilo Piazzalunga
8
Casi 3 años después y ninguno de los constructores adicionales se han agregado. :(
byxor
2
@BrandonIbbotson ¿Qué quieres decir con 'ellos' y dónde se agregan? Si lo que quiso decir con 'ellos' son constructores de superclase y con 'dónde' es subclase, entonces está equivocado. Los constructores de superclase no se agregan implícitamente a la subclase. Además, no puedo ver ningún otro tema en las oraciones anteriores para que esas palabras se refieran.
Halil
90

Una excepción personalizada típica que definiría es algo como esto:

public class CustomException extends Exception {

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

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

}

Incluso creo una plantilla usando Eclipse para no tener que escribir todo el material una y otra vez.

nanda
fuente
17
Simplemente puede extender la Excepción al crear su Clase en Eclipse y obtendrá los cuatro constructores. No necesitas una plantilla.
jeremyjjbrown
¿Cuándo deberíamos usar el segundo Consutructor en lugar del primero?
ZhaoGang
61

Si usa el cuadro de diálogo de nueva clase en Eclipse, puede configurar el campo Superclase java.lang.Exceptiony marcar "Constructores de la superclase" y generará lo siguiente:

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
    }

}

En respuesta a la siguiente pregunta acerca de no llamar super()al constructor defualt, Oracle tiene esto que decir :

Nota: Si un constructor no invoca explícitamente a un constructor de superclase, el compilador de Java inserta automáticamente una llamada al constructor sin argumentos de la superclase.

Kevin Brey
fuente
22

La razón de esto se explica en el artículo de Herencia de la Plataforma Java que dice:

"Una subclase hereda todos los miembros (campos, métodos y clases anidadas) de su superclase. Los constructores no son miembros , por lo que no son heredados por las subclases, pero el constructor de la superclase se puede invocar desde la subclase".

Isaq
fuente
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
fuente
¿Qué volvería esto?
user1876508
Simplemente imprimiría "Hola de nuevo con una excepción personalizada", que es del constructor de UseCusomException, la excepción se generaría y luego quedaría atrapada en el principal, que imprimiría "Esta es mi excepción personalizada: esta es una excepción personalizada".
ThePerson
2

La clase de excepción tiene dos constructores.

  • public Exception() - Esto construye una excepción sin ninguna información adicional. La naturaleza de la excepción generalmente se infiere del nombre de la clase.
  • public Exception(String s) - Construye una excepción con un mensaje de error especificado. Un mensaje detallado es una Cadena que describe la condición de error para esta excepción en particular.
Deepak Pakhale
fuente
3
En realidad, desde Java 1.4, hay dos constructores más: public Exception(Throwable)y public Exception(String, Throwable). Son necesarios para soportar adecuadamente el encadenamiento de excepciones .
Danilo Piazzalunga
@DaniloPiazzalunga está de acuerdo contigo. fuente: Resumen del constructor docs.oracle.com/javase/1.5.0/docs/api/java/lang/Exception.html
KNU
0

Si hereda de Exception, debe proporcionar un constructor que tome un String como parámetro (contendrá el mensaje de error).

vulkanino
fuente
Creo que deberías agregar razón también.
Jigar Joshi el
3
En realidad, eso es incorrecto. Si su código usa un constructor con un argumento String, entonces debe declararlo. Sin embargo, una subclase de excepción se puede definir sin constructores explícitos ... porque la excepción tiene un constructor sin argumentos.
Stephen C
0

y no olvides la forma más fácil de lanzar una excepción (no necesitas crear una clase)

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