2010-01-25 14 views
27

sobrecarga asociada con excepción vs Throwable en Java

throw new Exception(); 

tiene una muy gran sobrecarga, ya que crea un StackTrace completa, etc.
¿Se

throw new Throwable(); 

presentan el mismo problema? ¿Se hereda este comportamiento, o arrojar un Throwable tiene una sobrecarga (o no) más pequeña?

EDITAR
Desde un punto de vistaanalista, un usuario insertar una contraseña incorrecta es una excepción a la orden de ejecución normal de un programa. Así que si tengo:

public Session newSession() { 
    validate_user_and_password(); 
} 

lanzar una UserNotValidException sonaría correcto desde un analistas punto de vista.
De vuelta null o 0 suena incorrecto si su código tiene bastante buena abstracción. Solo quería saber si realmente podría implementar esto en el código, o si tendría que dejarlo a la teoría.

Hay una buena diferencia entre la excepción del punto de vista de programación y la excepción del punto de vista del analista.

Nota: He dado un ejemplo muy simple y tonto, este no es exactamente mi caso.
Nota 2: Sé que devolver null sería lo normal, pero debo tener el código OO correctamente abstraído y, personalmente, no veo ningún daño en esto.

+10

¿Por qué esta preocupación? ¿Cuál es el requisito funcional? – BalusC

+2

No debe usar excepciones en el caso regular de todos modos, solo deben usarse en * exception * al circunstancias. –

+0

@anon deberían usarse para "rutas de código excepcionales" que pueden o no ser tan excepcionales como podría pensarse. Por ejemplo, si evita completar el seguimiento de la pila, lo mejor es utilizarlos para señalar el final de una secuencia en lugar de verificar el final después de cada lectura. (Sin embargo, esto no se aplica al bucle sobre matrices, donde la VM conoce la longitud completa). – akuhn

Respuesta

49

Throwable también crea un stacktrace cuando se crea. Desde java docs for Throwable:

throwable contiene una instantánea de la pila de ejecución de su subproceso en el momento en que se creó.

Así que en términos de gastos generales con respecto a la creación de un StackTrace, no debería haber ninguna diferencia entre Exception y Throwable.

Si está utilizando excepciones para "eventos excepcionales" (como debería ser), entonces no debería preocuparse demasiado por la sobrecarga de una pila. Un evento excepcional ocurre raramente en el código de ejecución. Por lo tanto, las excepciones no deberían afectar el rendimiento del código normal de ninguna manera significativa.

37

No, necesitas tu propia subclase para evitar ese efecto.

Exception ex = new Exception() { 
    @Override public Throwable fillInStackTrace() { 
     return this; // and do nothing else 
    } 
}; 

Esto crea una instancia de excepción que no llenará el seguimiento de la pila (la creación de delegados excepciones a fillInStackTrace para llenar realmente el seguimiento de la pila) y por lo tanto barata de crear.

+1

Parece que 'return null;' hará lo mismo que 'return this;'. ¿Alguna razón por la que desearía usar 'return this;'? – mangoDrunk

+10

Para cumplir con la documentación API de Throwable. – akuhn

+3

Pero está rompiendo "Este método registra dentro de este objeto Throwable información sobre el estado actual de los marcos de pila para el hilo actual." Editar: Pero punto tomado, buen truco! – mangoDrunk

3

Con la compilación de JIT, en realidad todavía no es el caso de que se escuche mucho al lanzar un Exception en Java. Pero arrojar un Throwable no es muy diferente, ya que también obtendrá un seguimiento de la pila allí.

Si le interesa, hay un documento muy interesante llamado "Manejo eficiente de excepciones Java en la compilación justo a tiempo" (link). No es una lectura ligera, pero bastante informativa.

+1

¿Puede proporcionar una referencia para eso? Creo que crear un rastro de pila es aún más caro cuando tienes JIT, ya que tienes que desoptimizar para recuperar el rastro de la pila real. – akuhn

+0

Sí, referencia añadida. – danben

+1

IIRC, he medido más de 10k ciclos desde la creación de una excepción. Eso fue hace unos años. Probablemente será más con rastros de pila "marco" completos. –

0

java.lang.Exception se extiende java.lang.Throwable, por lo que es la misma sobrecarga. De Javadoc:

La clase de Throwable es la superclase de todos los errores y excepciones en el lenguaje de Java. Solo los objetos que son instancias de esta clase (o una de sus subclases) son lanzados por la Máquina Virtual de Java o pueden ser lanzados por la declaración Java throw. De forma similar, solo esta clase o una de sus subclases puede ser el tipo de argumento en una cláusula catch.

Las instancias de dos subclases, Error y Excepción, se usan convencionalmente para indicar que se han producido situaciones excepcionales. Normalmente, estas instancias se crean recientemente en el contexto de la situación excepcional para incluir información relevante (como datos de seguimiento de pila).

+2

Esa lógica no tiene sentido, las subclases pueden presentar mucha más complejidad. Por supuesto, en este caso no es así, pero ese hecho no hace que tu respuesta sea menos inútil. –

1

Nunca debe ser tirar o la captura de Throwable. El alcance de la excepción es demasiado grande.

Como se indicó anteriormente, las excepciones se deben usar solo cuando sea necesario, es decir: en circunstancias excepcionales y deben ser específicas a la situación que las generó. Aparte de eso, capturar un Throwable implica una serie de excepciones, como OutOfMemoryException. Un error de esta magnitud no se puede recuperar de (fácilmente) y no debe ser manejado por el desarrollador.

+0

Acepto, nunca se debe lanzar un nuevo Throwable() ', pero [al momento de hacer mi pregunta original], estaba considerando' lanzar una nueva MyNonStackTracedException() 'donde' MyNonStackTracedException se extiende Throwable' (si no había gastos generales) . – WhyNotHugo

+0

Su consejo no es muy bueno. Decirles a los programadores que * no deberían * manejar las excepciones es un poco tonto. Por lo menos, puede querer decirle a su usuario "hey, nos quedamos sin memoria: (" antes de que bloquee su programa en el suelo. –

+2

Está malinterpretando. El OP preguntó acerca de tirar 'Throwable' o' Exception'. 'Throwable' necesita atrapar' Throwable' que tiene muchos, muchos problemas relacionados con él. – gpampara

1

Throwable es la clase principal de Exception. por lo que Exception class se hereda de Throwable.

0

Throwable vs. Exception

Java Exception

Como @mangoDrunk dijo: "Throwable es la superclase de excepción y error."

+0

Superclase, según lo que veo en la imagen incluida. – WhyNotHugo

1

Puede ver el código fuente de las dos clases para ver que Exception no hace nada más que exponer los mismos constructores como Throwable. Toda la carne, y por lo tanto sobrecarga, vive en Throwable.

Incluso si Exception introdujo alguna sobrecarga adicional, sería una clara sobre-optimización usar Throwable en su lugar. Use la herramienta adecuada para el trabajo, no coopte la herramienta equivocada solo porque es más liviana.

Cuestiones relacionadas