Java-数组的奇怪泛型行为

Java-数组的奇怪泛型行为,java,arrays,reflection,type-erasure,Java,Arrays,Reflection,Type Erasure,我试图用反射实现某种自定义序列化,然后我发现,如果A不是B的子类型,即使数组中的所有元素都是B的子类型,也不能将A[]转换为B[],因为在一天结束时,A[]和B两个元素都是B的子类型(由于类型擦除,它应该可以工作)[]是对象[]) 以下是我的意思的一个例子: 公共类Foo{ 公共静态void main(字符串[]args)引发异常{ 新的Foo().testGenerics(); } 公共链接列表strList; 公共字符串[]strArr; public void testGenerics()

我试图用反射实现某种自定义序列化,然后我发现,如果A不是B的子类型,即使数组中的所有元素都是B的子类型,也不能将
A[]
转换为
B[]
,因为在一天结束时,
A[]
B两个元素都是B的子类型(由于类型擦除,它应该可以工作)[]
对象[]

以下是我的意思的一个例子:

公共类Foo{
公共静态void main(字符串[]args)引发异常{
新的Foo().testGenerics();
}
公共链接列表strList;
公共字符串[]strArr;
public void testGenerics()引发异常{
LinkedList objList=新建LinkedList();
对象列表添加(“foo”);
Object[]objArr=新对象[1];
objArr[0]=“条形”;
Foo.class.getField(“strList”).set(这个,对象列表);
System.out.println(“列表[0]=”+strList.get(0));
System.out.println(“list len=“+strList.size());
Foo.class.getField(“strArr”).set(this,objArr);
System.out.println(“arr[0]=”+strArr[0]);
系统输出打印项次(“arr len=“+strArr.length”);
}
}
在本例中,列表工作正常,但数组在试图设置它的行处抛出异常


数组忽略类型擦除有什么原因吗?有什么好方法可以在运行时为给定类型创建数组和列表吗?

数组和泛型是完全不同的东西。泛型在运行时被擦除,因为JVM不知道它们。但是,JVM知道数组。如果在“数组”中搜索,您将看到它的标题是“数组”。但您找不到任何关于泛型或参数化类型的信息。您可以更详细地阅读第3.9节,了解JVM对数组的了解程度。Java语言规范也在非常不同的章节中讨论了数组

因此,JVM在运行时可以并且确实尝试维护数组的类型安全性,并阻止您将
Object[]
分配给
String[]
。这类似于Java编译器试图在编译时通过阻止您将
LinkedList
分配给
LinkedList
,来维护
LinkedList
的类型安全性。这并不像后者在运行时是“安全的”,只是运行时不知道如何阻止您

有没有什么好方法可以在运行时为给定类型创建数组和列表

给定
类clazz
长度
,可以通过以下方式创建它的数组:

Object o = Array.newInstance(clazz, length);
但不得不这么做闻起来像是……确保你知道自己在做什么


您可以使用当前使用的方式创建列表。它不是类型安全的,但这是JVM/Java的一个缺陷。

数组和泛型是非常不同的东西。泛型在运行时被擦除,因为JVM不知道它们。但是,JVM知道数组。如果您搜索“数组”,您会看到它的标题是“数组”。但是你找不到关于泛型或参数化类型的任何信息。你可以更详细地阅读第3.9节,了解JVM对数组的了解程度。Java语言规范也在非常不同的章节中讨论和讨论

因此,JVM在运行时可以并且确实尝试维护数组的类型安全性,并阻止您将
Object[]
分配给
String[]
。这类似于Java编译器试图在编译时通过阻止您将
LinkedList
分配给
LinkedList
,来维护
LinkedList
的类型安全性。这并不像后者在运行时是“安全的”,只是运行时不知道如何阻止您

有没有什么好方法可以在运行时为给定类型创建数组和列表

给定
类clazz
长度
,可以通过以下方式创建它的数组:

Object o = Array.newInstance(clazz, length);
但不得不这么做闻起来像是……确保你知道自己在做什么


您可以使用当前使用的方式创建列表。它不是类型安全的,但这是JVM/Java的一个缺陷。

“有没有任何理由数组忽略类型擦除”因为数组不是泛型的。它们是数组…变量
strArr
不是泛型定义的-它是
字符串[]
。因此,在运行时,您无法将
对象[]
引用分配给该变量。
objList
由于类型擦除,在运行时只是一个
列表
。这就是为什么您可以使用反射将任何列表粘贴在其中。“数组忽略类型擦除有什么原因吗?”“因为数组不是泛型的。它们是数组…变量
strArr
不是泛型定义的-它是一个
字符串[]
。因此在运行时,您不能分配
对象[]”
引用该变量。
objList
由于类型擦除,在运行时只是一个
列表
。这就是为什么可以使用反射将任何列表粘贴在其中。啊,我明白了,很高兴知道数组不是泛型,我将研究该
数组。newInstance
如果我能找到一种方法来提取我明白了,很高兴知道数组不是泛型,我会研究这个
数组。newInstance
如果我能找到一种方法在运行时提取数组的类型,那就足够了。