scala生成的字节代码如何丢弃已检查的异常?

时间:2010-12-02 16:27:40

标签: java scala bytecode checked-exceptions

是否可以为应该抛出已检查异常的方法写入字节代码?

例如,除非方法声明它抛出已检查的异常,否则以下Java类不会编译:

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

虽然以下Scala等效(因为Scala没有检查异常):

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

即使生成的字节码几乎相同:

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

}

问题:是否有可能(以及如何)生成字节码,即使该方法中的代码无法处理,也不会标记它会抛出已检查的异常?

1 个答案:

答案 0 :(得分:13)

简单。虽然JVM字节码包含有关方法的已检查异常规范,但在执行任何字节码之前运行的字节码验证程序不会检查方法是否实际符合异常规范。您可以编写一个程序来获取现有的JVM字节码并删除所有异常规范,并且生成的字节码将完全有效并且与原始字节码完全相同(禁止反射)。