¿Es posible construir un fragmento de código en Java que pueda hacer que un hipotético sea java.lang.ChuckNorrisException
indescifrable?
Los pensamientos que se me ocurrieron están utilizando, por ejemplo, interceptores o programación orientada a aspectos .
java
exception
exception-handling
aop
Max Charas
fuente
fuente
finalize()
Qué tal una excepción que se vuelva a lanzar en el ?Respuestas:
No lo he intentado, así que no sé si la JVM restringiría algo como esto, pero tal vez podría compilar código que arroje
ChuckNorrisException
, pero en tiempo de ejecución proporcionar una definición de claseChuckNorrisException
que no extienda Throwable .ACTUALIZAR:
No funciona Genera un error de verificador:
ACTUALIZACIÓN 2:
En realidad, puede hacer que esto funcione si deshabilita el verificador de código de bytes. (
-Xverify:none
)ACTUALIZACIÓN 3:
Para aquellos que siguen desde casa, aquí está el script completo:
Crea las siguientes clases:
Compilar clases:
Correr:
Comente "extiende RuntimeException" y recompile
ChuckNorrisException.java
solo :Correr:
Ejecutar sin verificación:
fuente
Object
lugar deThrowable
entonces? (El compilador no lo permitirá, pero como ya hemos deshabilitado el verificador, tal vez uno podría hackear elDespués de haber reflexionado sobre esto, he creado con éxito una excepción inalcanzable. Elegí nombrarlo
JulesWinnfield
, sin embargo, en lugar de Chuck, porque es una excepción de hongo-nube-colocación-madre. Además, puede que no sea exactamente lo que tenía en mente, pero ciertamente no se puede atrapar. Observar:Et voila! Excepción no capturada.
Salida:
Cuando tenga un poco más de tiempo, veré si no puedo pensar en otra cosa también.
Además, mira esto:
Provoca un desbordamiento de la pila; nuevamente, las excepciones permanecen sin capturar.
fuente
JulesWinfield
? ¿No se detendrá el sistema antes de lanzarlo?throw new Whatever()
es realmente dos partes:Whatever it = new Whatever(); throw it;
y el sistema muere antes de llegar a la segunda parte.class cn extends exception{private cn(){}}
Con tal excepción, obviamente sería obligatorio usar un
System.exit(Integer.MIN_VALUE);
del constructor porque esto es lo que sucedería si lanzara tal excepción;)fuente
while(true){}
lugar deSystem.exit()
.System.exit()
funcione instalando un administrador de seguridad que no lo permita. eso convertiría al constructor en una excepción diferente (SecurityException), que podría detectarse.Cualquier código puede atrapar Throwable. Entonces, no, cualquier excepción que cree será una subclase de Throwable y estará sujeta a ser atrapada.
fuente
hang
en un intento de atrapar a ChuckNorrisException: P(De acuerdo, técnicamente , esta excepción nunca se lanza, pero
ChuckNorrisException
no se puede lanzar una adecuada , te lanza primero).fuente
Cualquier excepción que arrojes tiene que extender Throwable, por lo que siempre se puede atrapar. Entonces la respuesta es no.
Si desea hacer que sea difícil de manejar, puede reemplazar los métodos
getCause(), getMessage()
,getStackTrace()
,toString()
para lanzar otrajava.lang.ChuckNorrisException
.fuente
catch(Throwable t)
solo lo almacena en variable, por lo que mis sugerencias solo se aplican en el siguiente bloque cuando el usuario quiere hacer frente a la excepciónMi respuesta se basa en la idea de @ jtahlborn, pero es un programa Java totalmente funcional , que puede empaquetarse en un archivo JAR e incluso implementarse en su servidor de aplicaciones favorito como parte de una aplicación web .
En primer lugar, definamos la
ChuckNorrisException
clase para que no bloquee JVM desde el principio (a Chuck realmente le encanta chocar JVMs BTW :)Ahora pasa a
Expendables
clase para construirlo:Y finalmente la
Main
clase para patear un trasero:Compile y ejecútelo con el siguiente comando:
Obtendrá el siguiente resultado:
No es de extrañar, es una patada giratoria después de todo :)
fuente
En el constructor, puede iniciar un hilo que llama repetidamente
originalThread.stop (ChuckNorisException.this)
El hilo podría atrapar la excepción repetidamente, pero seguiría lanzándolo hasta que muera.
fuente
No. Todas las excepciones en Java deben ser de subclase
java.lang.Throwable
, y aunque puede que no sea una buena práctica, puede detectar todo tipo de excepción de esta manera:Consulte la documentación de java.lang.Throwable para obtener más información.
Si está tratando de evitar las excepciones marcadas (las que deben manejarse explícitamente), entonces querrá subclasificar Error o RuntimeException.
fuente
En realidad, la respuesta aceptada no es tan buena porque Java debe ejecutarse sin verificación, es decir, el código no funcionaría en circunstancias normales.
¡AspectJ al rescate por la solución real !
Clase de excepción:
Aspecto:
Aplicación de muestra:
Salida:
fuente
Una variante del tema es el hecho sorprendente de que puede lanzar excepciones comprobadas no declaradas del código Java. Como no se declara en la firma de métodos, el compilador no le permitirá detectar la excepción en sí, aunque puede capturarla como java.lang.Exception.
Aquí hay una clase auxiliar que te permite lanzar cualquier cosa, declarada o no:
Ahora
throw SneakyThrow.sneak(new ChuckNorrisException());
arroja una ChuckNorrisException, pero el compilador se queja ensobre la captura de una excepción que no se produce si ChuckNorrisException es una excepción marcada.
fuente
Los únicos
ChuckNorrisException
s en Java deberían serOutOfMemoryError
yStackOverflowError
.De hecho, puedes "atraparlos" de la manera que
catch(OutOfMemoryError ex)
se ejecutará a en caso de que se lance la excepción, pero ese bloque automáticamente arrojará la excepción a la persona que llama.No creo que eso
public class ChuckNorrisError extends Error
funcione, pero podrías intentarlo. No encontré documentación sobre extenderError
fuente
Is it possible to construct a snippet of code in java that would make a hypothetical java.lang.ChuckNorrisException uncatchable?
Sí, y aquí está la respuesta: diseñe su
java.lang.ChuckNorrisException
tal que no sea una instancia dejava.lang.Throwable
. ¿Por qué? Un objeto que no se puede lanzar es inalcanzable por definición porque nunca se puede atrapar algo que nunca se puede lanzar.fuente
java.lang.ChuckNorrisException
deben ser una excepción, y mucho menos arrojablesPuede mantener a ChuckNorris interno o privado y encapsularlo o tragarlo ...
try { doChuckAction(); } catch(ChuckNorrisException cne) { /*do something else*/ }
fuente
Dos problemas fundamentales con el manejo de excepciones en Java son que usa el tipo de una excepción para indicar si se debe tomar una acción basada en ella, y que cualquier cosa que tome acción basada en una excepción (es decir, "atraparlo") se supone que se resuelve La condición subyacente. Sería útil tener un medio por el cual un objeto de excepción podría decidir qué manejadores deberían ejecutarse, y si los manejadores que se han ejecutado hasta ahora han limpiado las cosas lo suficiente como para que el presente método satisfaga sus condiciones de salida. Si bien esto podría usarse para hacer excepciones "imposibles de capturar", dos usos más grandes serían (1) hacer excepciones que solo se considerarán manejadas cuando estén atrapadas por un código que realmente sepa cómo lidiar con ellas,
finally
FooException
finally
bloque durante el desenrollado de aBarException
, ambas excepciones deben propagarse por la pila de llamadas; ambos deben ser atrapables, pero el desenrollado debe continuar hasta que ambos hayan sido atrapados). Desafortunadamente, no creo que haya alguna forma de hacer que el código existente de manejo de excepciones funcione de esa manera sin romper las cosas.fuente
finally
bloque se está limpiando de una excepción anterior, es muy posible que cualquiera de las excepciones, en ausencia de la otra, sea algo que el código esperaría manejar y continuar, pero que manejar uno e ignorar al otro sería malo. Sin embargo, no existe un mecanismo para producir una excepción compuesta que ambos manejadores procesen.Foo
puedan distinguir entre una excepción que seFoo
lanzó o deliberadamente quiere fingir que se lanzó, de una queFoo
no esperaba que ocurriera cuando era llamando a otro método. De eso debería tratarse la noción de excepciones "controladas".Es posible simular fácilmente una excepción no detectada en el hilo actual. Esto activará el comportamiento regular de una excepción no detectada y, por lo tanto, hará el trabajo semánticamente. Sin embargo, no necesariamente detendrá la ejecución del subproceso actual, ya que no se produce ninguna excepción.
Esto es realmente útil en situaciones (muy raras), por ejemplo, cuando
Error
se requiere un manejo adecuado , pero el método se invoca desde un marco que captura (y descarta) cualquieraThrowable
.fuente
Llame a System.exit (1) en el
finalize
, y simplemente arroje una copia de la excepción de todos los demás métodos, para que el programa salga.fuente