with retornar example custom create java exception throw

java - retornar - throw exception c#



¿Qué puedes arrojar en Java? (3)

La sabiduría convencional dice que solo se pueden lanzar objetos que extienden Throwable en Java, pero ¿es posible desactivar el verificador de bytecode y hacer que Java compile y ejecute código que arroje objetos arbitrarios, o incluso primitivas?

athrow la vista hacia el athrow la JVM y aparecerá el primer objref en la pila de operandos; pero ¿comprobaría si dicha referencia apunta a un Throwable en tiempo de ejecución?


[...] desactivar el verificador de código de bytes [...]

La verificación de bytecode es parte de la especificación de JVM, por lo que si la desactiva (o manipula la JVM de otras formas), puede, dependiendo de la implementación, hacer casi cualquier cosa (incluidas las primitivas de lanzamiento, etc.), supongo.

Cita de la especificación de JVM:

El objectref debe ser de tipo referencia y debe referirse a un objeto que sea una instancia de la clase Throwable o de una subclase de Throwable.

Es decir, su pregunta puede interpretarse como "Si una JVM se desvía de la especificación, ¿puede hacer cosas raras como arrojar primitivas?" Y la respuesta es, por supuesto, sí.


Como se menciona en la respuesta de John, puede deshabilitar la verificación (ubicar la clase en bootclasspath también debería funcionar), cargar y ejecutar una clase lanzando una clase no Throwable éxito.

Sorprendentemente, ¡no conduce necesariamente a un crash!

Siempre que no Throwable métodos de Throwable implícita o explícitamente, todo funcionará perfectamente bien:

.source ThrowObject.j .class public ThrowObject .super java/lang/Object .method public <init>()V aload_0 invokenonvirtual java/lang/Object/<init>()V return .end method .method public static main([Ljava/lang/String;)V new java/lang/Object dup invokenonvirtual java/lang/Object/<init>()V BeforeThrow: athrow AfterThrow: return CatchThrow: getstatic java/lang/System/out Ljava/io/PrintStream; ldc "Thrown and catched Object successfully!" invokevirtual java/io/PrintStream.println(Ljava/lang/String;)V return .catch all from BeforeThrow to AfterThrow using CatchThrow .end method

Resultado:

% java -Xverify:none ThrowObject Thrown and catched Object successfully!


Depende de su implementación de JVM. Según la especificación Java VM, es un comportamiento indefinido si el objeto no es Throwable .

El objectref debe ser de tipo referencia y debe referirse a un objeto que sea una instancia de la clase Throwable o de una subclase de Throwable.

En la sección 6.1, "El significado de ''Must''" :

Si alguna restricción ("debe" o "no debe") en una descripción de instrucción no se cumple en el tiempo de ejecución, el comportamiento de la máquina virtual Java no está definido.

Escribí un programa de prueba utilizando el ensamblador Jasmin que hace el equivalente de throw new Object() . La VM de Java HotSpot Server lanza un VerifyError :

# cat Athrow.j .source Athrow.j .class public Athrow .super java/lang/Object .method public <init>()V aload_0 invokenonvirtual java/lang/Object/<init>()V return .end method .method public static main([Ljava/lang/String;)V .limit stack 2 new java/lang/Object dup invokenonvirtual java/lang/Object/<init>()V athrow return .end method # java -jar jasmin.jar Athrow.j Generated: Athrow.class # java Athrow Exception in thread "main" java.lang.VerifyError: (class: Athrow, method: main signature: ([Ljava/lang/String;)V) Can only throw Throwable objects

La desactivación del verificador de athrow de athrow permite que el athrow ejecute y la JVM parece bloquearse cuando intenta imprimir los detalles de la excepción. Compare estos dos programas, el primero que arroja una Exception , el segundo que es el programa de prueba anterior que arroja un Object . Observe cómo sale en medio de una impresión:

# java -Xverify:none examples/Uncaught Exception in thread "main" java.lang.Exception at examples.Uncaught.main(Uncaught.j) # java -Xverify:none Athrow Exception in thread "main" #

Por supuesto, desactivar el verificador de bytecode es peligroso. La VM adecuada está escrita para suponer que se ha realizado la verificación del bytecode y, por lo tanto, no es necesario que compruebe los operandos de la instrucción de tipo. Tenga cuidado: el comportamiento indefinido que invoca cuando elude la verificación del código de bytes es muy parecido al comportamiento indefinido en los programas de C; puede suceder cualquier cosa, incluidos los demonios que salen volando de tu nariz.