2010-12-02 6 views
5

Wenn es möglich ist, Bytecode für eine Methode zu schreiben, die eine geprüfte Ausnahme auslösen soll?Wie lässt scala erzeugten Byte-Code die geprüfte Ausnahme fallen?

Zum Beispiel die folgende Java-Klasse kompiliert nicht, es sei denn die Methode erklärt er die geprüfte Ausnahme wirft:

public class CheckedExceptionJava { 
    public Class<?> testChecked(String s) throws ClassNotFoundException { 
    return Class.forName(s); 
    } 
} 

Während die folgende Scala Äquivalent funktioniert (weil Scala nicht Ausnahmen geprüft hat):

class CheckedException { 
    def testChecked(s : String) = Class.forName(s) 
} 

Auch wenn der Bytecode erzeugt sind fast identisch:

Compiled from "CheckedExceptionJava.java" 
public class CheckedExceptionJava extends java.lang.Object{ 
public CheckedExceptionJava(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: return 

public java.lang.Class testChecked(java.lang.String) throws java.lang.ClassNotFoundException; 
    Code: 
    0: aload_1 
    1: invokestatic #2; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; 
    4: areturn 

} 

Compiled from "CheckedException.scala" 
public class CheckedException extends java.lang.Object implements scala.ScalaObject{ 
public CheckedException(); 
    Code: 
    0: aload_0 
    1: invokespecial #24; //Method java/lang/Object."<init>":()V 
    4: return 

public java.lang.Class testChecked(java.lang.String); 
    Code: 
    0: aload_1 
    1: invokestatic #11; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; 
    4: areturn 

} 

Frage: Ist es möglich (und wie) Bytecode für das zu erzeugen, das nicht markiert wird, wirft es eine geprüfte Ausnahme ab, selbst wenn der Code innerhalb dieser Methode es nicht behandelt?

Antwort

13

Einfach. Während der JVM-Bytecode geprüfte Ausnahmespezifikationen für Methoden enthält, prüft der Bytecode-Verifizierer, der vor der Ausführung eines Bytecodes ausgeführt wird, nicht, ob die Methoden tatsächlich den Ausnahmespezifikationen entsprechen. Sie könnten ein Programm schreiben, das vorhandenen JVM-Bytecode verwendet und alle Ausnahmespezifikationen entfernt hat, und der resultierende Bytecode wäre perfekt gültig und würde identisch mit dem Original laufen (Sperrreflexion).

+0

Ohhh ich sehe. Wahrscheinlich mit einem Werkzeug wie Javassist? :) http://bit.ly/gNzXfA – OscarRyz

Verwandte Themen