2012-09-30 50 views
5

Lo que he sabido hasta ahora es que una subclase si se reemplaza un método de superclase debería arrojar la misma excepción o una subclase de la excepción.Cuál es el criterio para lanzar excepciones en la subclase

Por ejemplo:

esto es correcto

class SuperClass { 
    public int doIt(String str, Integer... data)throws ArrayIndexOutOfBoundsException{ 
String signature = "(String, Integer[])"; 
System.out.println(str + " " + signature); 
return 1; 
} 
} 

public final class SubClass extends SuperClass { 
    public int doIt(String str, Integer... data) throws ArrayIndexOutOfBoundsException { 
     String signature = "(String, Integer[])"; 
     System.out.println("Overridden: " + str + " " + signature); 
     return 0; 
    } 

    public static void main(String... args) { 
     SuperClass sb = new SubClass(); 
     try { 
      sb.doIt("hello", 3); 
     } catch (Exception e) { 
     } 
    } 
} 

Esta es incorrecta

class SuperClass { 
    public int doIt(String str, Integer... data)throws ArrayIndexOutOfBoundsException{ 
String signature = "(String, Integer[])"; 
System.out.println(str + " " + signature); 
return 1; 
} 
} 

public final class SubClass extends SuperClass { 
    public int doIt(String str, Integer... data) throws Exception { 
     String signature = "(String, Integer[])"; 
     System.out.println("Overridden: " + str + " " + signature); 
     return 0; 
    } 

    public static void main(String... args) { 
     SuperClass sb = new SubClass(); 
     try { 
      sb.doIt("hello", 3); 
     } catch (Exception e) { 
     } 
    } 
} 

Pero mi pregunta es, ¿por qué este bloque de código se considera correcta por el compilador ?

class SuperClass { 
    public int doIt(String str, Integer... data)throws ArrayIndexOutOfBoundsException{ 
String signature = "(String, Integer[])"; 
System.out.println(str + " " + signature); 
return 1; 
} 
} 

public final class SubClass extends SuperClass { 
    public int doIt(String str, Integer... data) throws RuntimeException { 
     String signature = "(String, Integer[])"; 
     System.out.println("Overridden: " + str + " " + signature); 
     return 0; 
    } 

    public static void main(String... args) { 
     SuperClass sb = new SubClass(); 
     try { 
      sb.doIt("hello", 3); 
     } catch (Exception e) { 
     } 
    } 
} 

Respuesta

5

Esto se debe a que en Java cada método puede lanzar una RuntimeException (o un Error) en cualquier momento. Ni siquiera necesita declararse en la parte throws de la firma de su método. Por lo tanto, también es posible lanzar una excepción que es un tipo súper declarado en el método reemplazado, siempre que siga siendo un subtipo de RuntimeException.

Ver Chapter 11 (Exceptions) of the Java Language Specification para la especificación para este comportamiento, especialmente 11.1.1. The Kinds of Exceptions cuales define comprobado (necesita ser especificado en throws cláusula) y sin marcar (no necesita ser especificado en throws cláusula) excepciones.

2

Cuando se reemplaza un método, se deben definir las mismas excepciones controladas. En este caso, el método SuperClass#doIt declara que arroja un ArrayIndexOutOfBoundsException, por lo que todos los niños que anulan ese método deben declarar las mismas excepciones marcadas o sus subclases.

Más información:

+0

¿Quiere decir, si una excepción de tiempo de ejecución es lanzada por el método de la superclase , cualquier superclase en la jerarquía de excepciones puede ser lanzada. –

+0

Excepción -> RuntimeException -> IndexOutOfBoundException -> ArrayIndexOutOfBoundException –

+0

Sí, eso es correcto. La excepción declarada en la anulación debe estar en su árbol descendiente, no puede ser más grande que la excepción declarada en la superclase. –

1

hacer un intento para que sea simple, y RuntimeExceptionError no necesita ser declarado en throws cláusulas, pero están siempre implícito. Si incluye las excepciones implícitas en la declaración, su declaración del método de la superclase podría escribirse;

public int doIt(String str, Integer... data) 
    throws ArrayIndexOutOfBoundsException, Error, RuntimeException { 

Eso significa, la declaración explícita RuntimeException en el método de la subclase es una subclase de una excepción existente (implícita) en el método de la superclase, por lo que está permitido.

0

Si el método de superclase no declara ninguna excepción, método reemplazado sub clase no puede declarar "marcada" excepción pero puede declarar excepciones "sin marcar"

Cuestiones relacionadas