tengo estas clases:
public class NegativeNumberException extends Exception{ NegativeNumberException() { System.out.println("Don't pass negative values!"); } public String getMessage() { String message="NegativeNumberException"; return message; } } public class Main { static void test(int n) throws NegativeNumberException { if(n<0) throw new NegativeNumberException(); else System.out.println("Success"); } public static void main(String[] args) { try { test(-5); } catch(NegativeNumberException nne) { System.out.println(nne); } } }Este es el resultado:
Dont pass negative values! NegativeNumberException: NegativeNumberException Esperaba que imprimiera NegativeNumberException una vez, supongo que si anulo getMessage se ejecuta sin importar qué, ¿es correcto o está sucediendo algo más?
Todos los objetos tienen una implementación toString() . Porque java.lang.Object en sí mismo (y Exception extends Throwable , y Throwable extends Object - todas las cosas eventualmente extienden el objeto) tiene esto.
La clase Throwable anula su implementación con:
@Override public String toString() { String s = getClass().getName(); String message = getLocalizedMessage(); return (message != null) ? (s + ": " + message) : s; } y getLocalizedMessage() se implementa como:
public String getLocalizedMessage() { return getMessage(); } cada vez que 'agrega' un objeto a una cadena (con X + Y , donde la expresión X tiene el tipo String e Y es cualquier cosa) es una abreviatura de X.concat(Y.toString()) . Por lo tanto, estás llamando a String allí. No lo anuló, por lo que obtiene la implementación de Throwable, que invoca getLocalizedMessage, que tampoco anuló, por lo que llama a getMessage(), por lo tanto, obtiene su texto. Dos veces.
Algunas lecciones:
System.out nada en los constructores de excepción. La excepción va a algún lugar y si necesita impresión, donde sea que termine, se imprimirá. Si una excepción termina 'finalizando' su método static void main(String[]) , java lo imprimirá por usted.NegativeNumberException probablemente debería tener el número real como mensaje, o posiblemente el nombre del parámetro. Algo como: public class NegativeNumberException extends Exception { public NegativeNumberException(String msg) { super(msg); } }y luego en su método de prueba:
if (n < 0) throw new NegativeNumberException("n: " + n); getMessage y devolver alguna constante de cadena casi nunca es correcto. Los mensajes rara vez deben ser constantes, ya que están destinados a detallar los detalles del problema, no para explicar en general lo que representa la excepción (escriba algún javadoc para eso, y solo si el nombre de la excepción no es suficiente para resolverlo, por lo tanto , no se necesita nada aquí).