繁体   English   中英

将对象数组转换为类型参数的数组

[英]Down casting Object array to array of type parameter

GenericArrayCreationIsDisallowedInJava构造函数中的语句如何工作? 有人可以解释一下吗?

public class GenericArrayCreationIsDisallowedInJava<I> {


    private I[] i;


    public GenericArrayCreationIsDisallowedInJava(int n)
    {
        i = (I[]) new Object[n];//works and prints out "Created". How?
        System.out.println("Created");
    }

    public static void main(String[] args) {

        new GenericArrayCreationIsDisallowedInJava<String>(2);

        String[] strs = (String[])  new Object[2]; // throws ClassCastException. When this statement doesn't work, how is the "(I[]) new Object[n]" statement working? 

    }

}
i = (I[]) new Object[n];

您对上述内容的看法尚不完全清楚,但最不明确的一件事是创建I数组。 负责选择数组类型的唯一部分是在new关键字之后:它是Object的数组,不安全地强制转换为I[]

编译器必须允许该行进行编译,因为它对I类型一无所知:它也可以是Object ,因此该行是合法的。

还要注意, I[]擦除类型是Object[]i变量的实际类型(在字节码中)是Object[] 因此,无论实例使用哪种类型的参数,赋值都会在运行时成功完成。

仅当将数组分配回可更改的类型时,才会引发ClassCastException 例如:

GenericArrayCreationIsDisallowedInJava o =
        new GenericArrayCreationIsDisallowedInJava<String>(2);

String[] strs = o.i; // ClassCastException thrown here

在类型擦除过程中,编译器将强制类型转换为String[]插入分配strs的行中。 这表明需要防止i泄漏到正在使用它的类之外。

要了解发生了什么,只需在类型擦除之后考虑相同的代码即可(只需删除类型参数并在必要时插入强制类型转换):

public class GenericArrayCreationIsDisallowedInJava {


    private Object[] i;


    public GenericArrayCreationIsDisallowedInJava(int n)
    {
        i = (Object[]) new Object[n];//works and prints out "Created". How?
        System.out.println("Created");
    }

    public static void main(String[] args) {

        new GenericArrayCreationIsDisallowedInJava(2);

        String[] strs = (String[])  new Object[2]; // throws ClassCastException. When this statement doesn't work, how is the "(I[]) new Object[n]" statement working? 

    }

}

暂无
暂无

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

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