Vis*_*ant 18 java compiler-construction generics inheritance throwable
编译时错误:泛型类可能不是java.lang.Throwable的子类
public class TestGenericClass<E> extends Exception {
/*Above line will give compile error, the generic class TestGenericClass<E> may
not subclass java.lang.Throwable*/
public TestGenericClass(String msg) {
super(msg);
}
}
Run Code Online (Sandbox Code Playgroud)
上面的编译时错误是出于以下§jls-8.1.2中给出的原因,并在此问题中进行了解释:
如果泛型类是Throwable(第11.1.1节)的直接或间接子类,则是编译时错误.
由于Java虚拟机的catch机制仅适用于非泛型类,因此需要此限制.
题:
如何限制子类java.lang.Throwable不是泛型类?
或者更通用的问题是,如何限制任何类的子类不能通用?
Jk1*_*Jk1 20
如何限制java.lang.Throwable的子类不是泛型类?
以下是OpenJDK编译器执行检查的方式:
import com.sun.tools.javac.code.Symbol.*;
private void attribClassBody(Env<AttrContext> env, ClassSymbol c) {
....
// Check that a generic class doesn't extend Throwable
if (!c.type.allparams().isEmpty() && types.isSubtype(c.type, syms.throwableType))
log.error(tree.extending.pos(), "generic.throwable");
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,禁用类型是一种带编码的类型,因此如果没有编译器代码自定义,您不能对自定义类使用相同的技术.
chr*_*her 10
如何限制java.lang.Throwable的子类不是泛型类?
这是决定将特殊情况编写到编译器本身.原因在于这个问题详述.基本上,这与可再生类型有关.你可以在这里阅读这个术语.简而言之,如果类型在编译时完全可用,则类型是可重新生成的.例如,通用类型是不可恢复的,因为它们的类型通过类型擦除来删除.出现在catch块中的对象需要是可恢复的.
或者更通用的问题,如何限制类的子类不能通用?
那么有几个选择..
目前,在Java的正常范围内没有选项可以做到这一点.它没有某种final实现阻止将泛型应用于子类.正如评论中所解释的,您可以得到的最接近的是扩展编译器并专门为您的类添加规则.这个解决方案让我的脊椎发抖.躲闪吧.这意味着您的代码只会使用您的Java版本,并且任何想要使用您的代码的人都必须安装相同的版本.
显然,另一种选择是扩展Throwable,但这确实不是一个好主意.它为您的类添加了大量功能,并为您的类的接口添加了许多新方法,您永远不会使用它们.从OOP的角度来看,为了拥有此功能,您牺牲了班级的完整性.
| 归档时间: |
|
| 查看次数: |
1109 次 |
| 最近记录: |