gpt4 book ai didi

java - 如何删除泛型 "replace"多个边界

转载 作者:行者123 更新时间:2023-12-01 22:31:15 24 4
gpt4 key购买 nike

我读到,在类型删除过程中,Java 编译器会删除所有类型参数,如果类型参数有界,则用其第一个界限替换每个参数,如果类型参数无界,则用 Object 替换。但是,我无法理解,指定类型参数需要实现的接口(interface)不是多余的吗。例如:

public class Box<T extends Something,Seralizable,Cloneable>

如果删除将类 Box 中的 T 替换为 Something (类引用),这是否意味着接口(interface):Seralizable ,Cloneable 必须由 Something 类实现,所以只有我觉得指定 Seralizable,Cloneable 接口(interface)是多余的?此外,如果菱形内部仅提及接口(interface),会发生什么情况,默认情况下 T 是否将其视为 Object 引用?

我很高兴能提供一个泛型类的示例和一个泛型方法的示例(如果泛型方法中存在多个扩展)。

最佳答案

您实际上已经回答了您的问题:如果类型不受限制,则删除是第一个边界或对象。让我们看几个例子:

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>您无法比较 Box 中的两项使用compareTo方法只是因为A没有实现Comparable 。如果您希望您的盒子元素是一流的A 实现Comparable接口(interface),您需要指定两个边界。

这不是 A实现 Comparable 的引用但是T引用!即使删除T extends A & Comparable<T>将是A编译器仍然可以在较低级别上执行强制转换。这就是这里正在发生的事情。如果您使用javap检查字节码,您可以看到这一点。实用程序其中 checkcast使用指令:

  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
....

关于java - 如何删除泛型 "replace"多个边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58549511/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com