看看这个(可以说是愚蠢的)代码:
public <T extends Appendable & Closeable> void doStuff(T object)
throws IOException{
object.append("hey there");
object.close();
}
我知道编译器删除了一般信息,所以我对编译器所做的Java 1.4代码感兴趣(我很确定编译器没有重新安排源代码,所以我要求一个等价的像我这样天真的人可以理解的Java源代码版本)
是这样的:
public void doStuff(Object object)
throws IOException{
((Appendable)object).append("hey there");
((Closeable)object).close();
}
或者更喜欢这样:
public void doStuff(Object object)
throws IOException{
Appendable appendable = (Appendable) object;
Closeable closeable = (Closeable) object;
appendable.append("hey there");
closeable.close();
}
或者甚至喜欢这样:
public void doStuff(Appendable appendable)
throws IOException{
Closeable closeable = (Closeable) appendable;
appendable.append("hey there");
closeable.close();
}
还是另一个版本?
答案 0 :(得分:14)
方法的签名看起来像public void doStuff(Appendable appendable)
,因为
绑定中类型的顺序是 唯一重要的是,类型变量的擦除由第一种类型决定 在它的绑定中,类类型或类型变量可能只出现在第一个中 位置。
如果使用反射来访问此方法,则此行为可能很重要。
此行为的另一个用途是保留与预通用接口的二进制兼容性,如 Generics Tutorial ,第10节中所述(感谢Mark Peters指出它)。也就是说,
public static <T extends Object & Comparable<? super T>> T max(Collection<T> coll)
与返回Object
的预通用版本二进制兼容。
方法体等同于以下内容,但我认为它是实现细节:
appendable.append("hey there");
((Closeable) appendable).close();
答案 1 :(得分:4)
我等不及了,我不得不回答我自己的问题。答案是我的第一个和第三个版本的组合:第一个绑定用作变量类型,并且对象在需要时被转换为第二个绑定。这是生成的字节代码(为了便于阅读,我添加了一个换行符):
// Method descriptor #20 (Ljava/lang/Appendable;)V
// Signature: <T::Ljava/lang/Appendable;:Ljava/io/Closeable;>(TT;)V
// Stack: 2, Locals: 2
public void doStuff(java.lang.Appendable object) throws java.io.IOException;
0 aload_1 [object]
1 ldc <String "hey there"> [26]
3 invokeinterface java.lang.Appendable.append(java.lang.CharSequence) :
java.lang.Appendable [28] [nargs: 2]
8 pop
9 aload_1 [object]
10 checkcast java.io.Closeable [34]
13 invokeinterface java.io.Closeable.close() : void [36] [nargs: 1]
18 return
Line numbers:
[pc: 0, line: 14]
[pc: 9, line: 15]
[pc: 18, line: 17]
Local variable table:
[pc: 0, pc: 19] local: this index: 0 type: rumba.dumba.Bumba
[pc: 0, pc: 19] local: object index: 1 type: java.lang.Appendable
Local variable type table:
[pc: 0, pc: 19] local: object index: 1 type: T