在 Java 中,定义泛型异常类是非法的。编译器将拒绝编译以下内容:
public class Foo<T> extends Throwable {
// whatever...
}
但是,这个 Scala 代码编译得很好:
class Foo[T](val foo: T) extends Throwable
更奇怪的是,只要我捕捉到原始Foo
类型,我就可以在 Java 代码中使用这个 Scala 类:
public class Main {
public static void main(String[] args) {
try {
throw new Foo<String>("test");
}
catch(Foo e) {
System.out.println(e.foo());
}
}
}
这会编译、运行和打印“test”。
这是根据 JLS 和 JVM 规范明确定义的,还是只是偶然发生的?
Java 对泛型异常的限制是纯粹的语言限制,还是也适用于字节码(在这种情况下,Scala 编译器生成的字节码将无效)?
编辑:这是 Scala 类在反编译后的样子:
public class Foo<T> extends java.lang.Throwable {
public T value();
Code:
0: aload_0
1: getfield #15 // Field value:Ljava/lang/Object;
4: areturn
public Foo(T);
Code:
0: aload_0
1: aload_1
2: putfield #15 // Field value:Ljava/lang/Object;
5: aload_0
6: invokespecial #22 // Method java/lang/Throwable."<init>":()V
9: return
}