繁体   English   中英

Java - 奇怪的 generics 行为与 arrays

[英]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 语言规范还在非常不同的部分讨论了arraysgenerics

因此,JVM 在运行时可以并且确实尝试维护 arrays 的类型安全,并阻止您将Object[]分配给String[] 这类似于 Java 编译器试图通过阻止您将LinkedList<Object>分配给LinkedList<String> > 来在编译时维护LinkedList的类型安全。 这并不像后者在运行时以某种方式“安全地做”,只是运行时不知道足以阻止你。

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

给定Class<?> clazzlength ,您可以通过以下方式创建它的数组:

Object o = Array.newInstance(clazz, length);

但是必须这样做闻起来像一个XY 问题......确保你知道你在做什么。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM