Java编译器对多个泛型边界做了什么?

Sea*_*oyd 13 java generics type-erasure

看看这个(可以说是愚蠢的)代码:

public <T extends Appendable & Closeable> void doStuff(T object)
throws IOException{

    object.append("hey there");
    object.close();

}
Run Code Online (Sandbox Code Playgroud)

我知道编译器删除了通用信息,所以我对编译器所做的Java 1.4代码感兴趣(我很确定编译器没有重新安排源代码,所以我要求一个等效的Java源代码版本像我这样天真的人可以理解)

是这样的:

public void doStuff(Object object)
throws IOException{

    ((Appendable)object).append("hey there");
    ((Closeable)object).close();

}
Run Code Online (Sandbox Code Playgroud)

或者更喜欢这样:

public void doStuff(Object object)
throws IOException{
    Appendable appendable = (Appendable) object;
    Closeable closeable = (Closeable) object;

    appendable.append("hey there");
    closeable.close();

}
Run Code Online (Sandbox Code Playgroud)

或者甚至像这样:

public void doStuff(Appendable appendable)
throws IOException{
    Closeable closeable = (Closeable) appendable;

    appendable.append("hey there");
    closeable.close();

}
Run Code Online (Sandbox Code Playgroud)

还是另一个版本?

axt*_*avt 14

该方法的签名看起来像public void doStuff(Appendable appendable),因为

绑定中类型的顺序仅在于,类型变量的擦除由其边界中的第一个类型确定,并且类类型或类型变量可能仅出现在第一个位置.

(JLS§4.4类型变量)

如果您使用反射来访问此方法,则此行为可能很重要.

此行为的另一个用途是保留与预通用接口的二进制兼容性,如中所述 泛型教程第10节(感谢Mark Peters指出它).那是,

public static <T extends Object & Comparable<? super T>> T max(Collection<T> coll)
Run Code Online (Sandbox Code Playgroud)

与其预先通用版本返回二进制兼容Object.


方法体相当于以下内容,但我认为它是实现细节:

appendable.append("hey there"); 
((Closeable) appendable).close(); 
Run Code Online (Sandbox Code Playgroud)

  • +1,您还可以查看泛型教程,第10节(http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf),它检查了`Collections.max()`的情况.`max()`使用多个边界`<T extends Object&Comparable <?super T >>`用Generics改装后保持二进制兼容性. (3认同)