public class Generic<T extends Object & Appendable & AutoCloseable> {
T t;
T method() throws Exception {
t.close();
char c='\u0000';
t.append(c);
return t;
}
public <T> T method2(T t) {
return t;
}
}
类型参数T不应该被视为Object吗? (因此不允许我调用 close() 或append())??
多重绑定。
具有多个边界的类型变量是所有类型的子类型 列在绑定中。如果其中一个边界是类,则它必须是 首先指定。因此调用AutoCloseable接口中包含的close()方法和Appendable接口中包含的append()方法在语法上是合法的。
t
是对象类型。 指令
checkcast
是在调用接口方法之前生成的。 如果
t
的值未实现该接口,则将抛出 ClassCastException。
Compiled from "Generic.java"
public class Generic<T extends java.lang.Appendable & java.lang.AutoCloseable> {
T t;
public Generic();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
T method() throws java.lang.Exception;
Code:
0: aload_0
1: getfield #2 // Field t:Ljava/lang/Object;
4: checkcast #3 // class java/lang/AutoCloseable
7: invokeinterface #4, 1 // InterfaceMethod java/lang/AutoCloseable.close:()V
12: iconst_0
13: istore_1
14: aload_0
15: getfield #2 // Field t:Ljava/lang/Object;
18: checkcast #5 // class java/lang/Appendable
21: iload_1
22: invokeinterface #6, 2 // InterfaceMethod java/lang/Appendable.append:(C)Ljava/lang/Appendable;
27: pop
28: aload_0
29: getfield #2 // Field t:Ljava/lang/Object;
32: areturn
public <T> T method2(T);
Code:
0: aload_1
1: areturn
}
最左规则并不完全相关 - 我仍在尝试找出正确的JLS
部分(并不像我希望的那么容易),但是您可以从这里看到该类型不是对象:
<T extends Object & Appendable & AutoCloseable> void whatType(T... args) {
System.out.println(args.getClass().getComponentType().getSimpleName());
}
new DeleteMe().whatType(); // prints AutoCloseable
bound中定义的所有方法。因此,允许使用 Object 、 Appendable 和 Autocloseable 的方法。类型擦除和允许的方法并不相互依赖。引入类型擦除只是为了防止运行时产生额外的开销。