[英]Java - weird generics behavior with arrays
我试图用反射实现某种自定义序列化,然后我发现如果 A 不是 B 的子类型,即使数组中的所有元素都是子类型,你也不能将A[]
转换为B[]
B(它应该因为类型擦除而起作用,因为在一天结束时a[]
和b[]
都是Object[]
)。
这是我的意思的一个例子:
public class Foo {
public static void main(String[] args) throws Exception {
new Foo().testGenerics();
}
public LinkedList<String> strList;
public String[] strArr;
public void testGenerics() throws Exception {
LinkedList<Object> objList = new LinkedList<Object>();
objList.add("foo");
Object[] objArr = new Object[1];
objArr[0] = "bar";
Foo.class.getField("strList").set(this, objList);
System.out.println("list[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]);
System.out.println("arr len = " + strArr.length);
}
}
在此示例中,列表工作正常,但数组在尝试设置它的行处引发异常。
arrays 是否有任何理由忽略类型擦除,是否有任何好方法可以在运行时为给定类型创建数组和列表?
Arrays 和 generics 是非常不同的东西。 Generics 在运行时被擦除,因为 JVM 不知道它们。 但是,JVM确实知道 arrays。 如果您在JVM 规范中搜索“array”,您会看到第 3.9 节的标题为“Arrays”。 但是您找不到任何关于 generics 或参数化类型的信息。 您可以更详细地阅读第 3.9 节,以了解 JVM 对 arrays 了解多少。 Java 语言规范还在非常不同的部分讨论了arrays和generics 。
因此,JVM 在运行时可以并且确实尝试维护 arrays 的类型安全,并阻止您将Object[]
分配给String[]
。 这类似于 Java 编译器试图通过阻止您将LinkedList<Object>
分配给LinkedList<String>
> 来在编译时维护LinkedList
的类型安全。 这并不像后者在运行时以某种方式“安全地做”,只是运行时不知道足以阻止你。
有什么好方法可以在运行时为给定类型创建数组和列表吗?
给定Class<?> clazz
和length
,您可以通过以下方式创建它的数组:
Object o = Array.newInstance(clazz, length);
但是必须这样做闻起来像一个XY 问题......确保你知道你在做什么。
您可以使用您现在使用的方式创建一个列表。 它不是类型安全的,但这是 JVM/Java 的一个缺陷。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.