1 回答
TA贡献1807条经验 获得超9个赞
您实际上已经回答了您的问题:如果类型不受限制,则擦除是第一个边界或对象。让我们看几个例子:
public class A implements Serializable {
// since the first bound is Cloneable, the erasure is Cloneable
static <T extends Cloneable & Serializable> void doSomething1(T t) {}
// since the first bound is Serializable, the erasure is Serializable
static <T extends Serializable & Cloneable> void doSomething2(T t) {}
// since T is not bounded, the erasure is Object
static <T> void doSomething(T t) {
System.out.println("A");
}
// the type of A is a class, so it has to come first
// the erasure is A since it comes first
static <T extends A & Serializable> void doSomething(T t) {
System.out.println("B");
}
// not possible because the bounds are two classes
// static <T extends Object & A> void doSomething(T t) {return null;}
}
由于擦除不同,方法可以具有相同的名称!但这是完全不推荐的,而且相当令人困惑,因为行为发生了变化:
public static void main(String[] args) {
A.doSomething(new Object()); // prints "A"
A.doSomething(new A()); // prints "B"
}
编辑后回答您的问题:不,这并不多余。指定类型参数需要实现的类型使您可以访问边界的方法。让我们看一下下面的例子:
public final class Box<T extends A & Comparable<T>> {
private T item1;
private T item2;
int compare() {
// this is the compare method of Comparable interface
return item1.compareTo(item2);
}
}
从上面的示例中您可以看到它A没有实现该Comparable接口。这意味着,如果您只是编写,则无法简单地比较使用该方法Box<T extends A>中的两项,因为没有实现。如果您希望框项属于类并实现接口,则需要指定两个边界。BoxcompareToAComparableA Comparable
A实现的不是参考Comparable,而是T参考!即使删除了T extends A & Comparable<T>will,A编译器仍然可以在较低级别上执行转换。这就是这里正在发生的事情。如果您使用使用checkcastjavap指令的实用程序检查字节码,您可以看到这一点:
int compare();
....
0: aload_0
1: getfield #7 // Field item1:LA;
4: checkcast #13 // class java/lang/Comparable
7: aload_0
8: getfield #15 // Field item2:LA;
11: invokeinterface #18, 2 // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
16: ireturn
....
添加回答
举报