gpt4 book ai didi

java泛型类型删除

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:15:38 25 4
gpt4 key购买 nike

当声明一个带有类型参数的类时 <T extends A & B & C> , 类型删除过程将替换 T与类型 A .但是如果变量类型为 T调用接口(interface)中声明的方法 BC , Java 用它做什么?

当我们创建一个泛型实例时,例如 ArrayList<String> , 类型参数 String也将被删除,但调用 get方法将返回类型 String , 这些信息被删除后从何而来?

我知道使用了java反射,但我需要一些具体的解释。

最佳答案

不使用反射 - 使用转换。例如,拿这段代码:

interface A {
void a();
}

interface B {
void b();
}

interface C {
void c();
}

class Generic<T extends A & B & C> {
T t;

Generic(T t) {
this.t = t;
}

void callMethods() {
t.a();
t.b();
t.c();
}
}

现在查看 Generic 的字节码(已移除构造函数):

class Generic extends java.lang.Object{
A t;

void callMethods();
Code:
0: aload_0
1: getfield #2; //Field t:LA;
4: invokeinterface #3, 1; //InterfaceMethod A.a:()V
9: aload_0
10: getfield #2; //Field t:LA;
13: checkcast #4; //class B
16: invokeinterface #5, 1; //InterfaceMethod B.b:()V
21: aload_0
22: getfield #2; //Field t:LA;
25: checkcast #6; //class C
28: invokeinterface #7, 1; //InterfaceMethod C.c:()V
33: return
}

注意 checkcast每个 invokeinterface 之前的说明调用 b()c()

结果就像 Generic 实际上是这样写的:

class Generic<T extends A> {
T t;

Generic(T t) {
this.t = t;
}

void callMethods() {
t.a();
((B) t).b();
((C) t).c();
}
}

关于您关于 ArrayList 的问题 - 关于作为列表元素类型的 get() 返回类型的信息仍然作为 的一部分存储>ArrayList 类。编译器将再次在调用代码中插入强制转换,因此:

ArrayList<String> strings = new ArrayList<String>();
strings.add("foo");
String x = strings.get(0);

在执行时等同于:

ArrayList strings = new ArrayList();
strings.add("foo");
String x = (String) strings.get(0);

这方面的一个重要方面是您不能在执行时询问ArrayList 对象T 是什么 - 该信息已经已删除。

关于java泛型类型删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7963324/

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