在浏览一些有关java反射和泛型的Jakov Jenkov博客时,我发现了以下段落:
当运行时检查可参数化类型本身时,如
java.util.List
,无法知道参数化的类型。这是有道理的,因为类型可以参数化为同一应用程序中的所有类型。但是,当您检查声明使用参数化类型的方法或字段时,您可以在运行时看到参数化参数化类型的类型。
任何人都可以详细说明该段吗?
我对“当运行时检查可参数化类型本身”
时的语句感到困惑答案 0 :(得分:3)
考虑以下小程序:
import java.util.ArrayList;
class MyClass {
ArrayList<String> stringList;
public ArrayList<String> getStringList() {
return stringList;
}
}
public class Foo {
public static void main(String... args) throws NoSuchMethodException {
ArrayList<Integer> intList = new ArrayList<>();
System.out.println(intList.getClass().toGenericString());
System.out.println(MyClass.class.getMethod("getStringList").toGenericString());
}
}
该程序的输出是:
public class java.util.ArrayList<E>
public java.util.ArrayList<java.lang.String> MyClass.getStringList()
如您所见,intList
是ArrayList<Integer>
的事实在运行时是未知的,但MyClass.getStringList()
返回ArrayList<String>
的事实是。
原因是,所有ArrayList
个实例(其中一些可能是ArrayList<Integer>
和其他ArrayList<String>
)共享相同的Class
对象:
ArrayList<String> stringList = new ArrayList<>();
ArrayList<Integer> intList = new ArrayList<>();
System.out.println(stringList.getClass() == intList.getClass());
会输出true
。因此intList.getClass()
无法了解对象的类型参数。
另一方面,MyClass.getStringList()
返回的对象始终是字符串列表,可以在运行时看到此信息。
答案 1 :(得分:1)
请考虑您有以下课程:
public class ReflectionTest {
List<Integer> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
}
检查参数化类型本身意味着检查list1.getClass()
或list2.getClass()
。它们绝对难以区分:
System.out.println(list1.getClass() == list2.getClass());
// prints true
ArrayList
的所有实例都是同一个类的实例,无论参数化如何,因此只有list1.getClass()
或list2.getClass()
您无法确定它是否使用{{1}参数化}或Integer
。
但是,如果您可以直接访问该字段,则可以执行此操作:
String
因为在这里您正在访问字段本身,并且实际参数化与字段声明一起存储在类文件中。如果检查方法参数或返回值,则可以进行相同的操作:它的实际通用签名也会与删除的签名一起存储在类文件中。
答案 2 :(得分:0)
java中的泛型是一个编译时间的东西。没有办法在运行时获取泛型类型的任何信息,但非null 对象包含有关其类型的信息。
所以,如果你有一个方法,它需要List<T>
并且列表不为空,你可以做出类似的东西:
if (list.get(0) instanceOf X) {
// ...
}
如果你读了一些带有泛型的java代码,你会发现很多这样的方法:
<T> T getSomething(Class<T> aClass);
原因是,为什么需要携带类型的某个对象,就是在运行时根本没有泛型类型。
答案 3 :(得分:0)
简单来说,它只是表明该列表并不知道它所拥有和不关心的数据类型。当你调用一个方法时,你的程序会找出它在运行时的类型。
答案 4 :(得分:0)
请参阅这些文章:this one和another one以及one more。
他们解释了&#34;擦除机制&#34;。