gpt4 book ai didi

java - 泛型和类型删除

转载 作者:行者123 更新时间:2023-12-02 03:58:01 26 4
gpt4 key购买 nike

谁能向我解释一下为什么会发生这种情况:

public class Array<E> {

public E[] elements = (E[]) new Object[10];

public E get(int idx) {
return elements[idx]; // Ignore bound-checking for brevity.
}

public static void doSomething(Array<Integer> arr) {
Integer good = arr.get(0);
Integer bad1 = arr.elements[0];
Integer bad2 = ((Integer[]) arr.elements)[0];
Integer bad3 = (Integer) arr.elements[0];
// `bad1', `bad2', and `bad3' all produce a
// runtime exception.
}

public static void main(String[] args) {
Array<Integer> test = new Array<>();

Array.doSomething(test);
}
}

完整示例在这里:http://pastebin.com/et7sGLGW

我读过有关类型删除的内容,并意识到类型检查是在编译期间执行的,然后将 E 简单地替换为 Object,所以我们只有 public Object[] elements,但是为什么 get 方法能够成功,而常规类型转换却不能呢? get 方法的返回类型是否也会被删除?

谢谢。

最佳答案

尽管arr类型为Array<Integer> (并且 arr.elements 的类型为 Integer[] ), arr.elements实际上有运行时类型 Object[] ,因为实际数组是 Object[] 类型的实例.

(请注意,与泛型不同,数组协变的,并且具有删除功能。 Object[] foo = new String[5]; 是合法的 - 就像 String[] bar = (String[]) foo; 一样。而 Integer[] baz = (Integer[]) foo; 是合法的。会在运行时引发 ClassCastException。)

所以任何引用 arr.elements 的原因触发运行时异常的原因是编译器自动插入向下转换为 Integer[] ,使类型和运行时类型恢复一致。 doSomething体内, arr.elements实际上意味着(Integer[]) arr.elements ,带有隐式转换。

相比之下,在 get() 内,类型 this只是 Array<E> ,所以类型为 elements只是 E[] ,无法检查。因此编译器不会插入任何隐式转换。

<小时/>

主要的要点是(E[]) new Object[10];实际上不正确new Object[10]是否没有创建 E[] 的实例。编译器看不到它是不正确的,但它会插入大量的强制转换发现它是不正确的。

更好的方法是使用Object[] elements = new Object[] ,并从 Object 执行正确但未经检查的转换至E ,必要时,而不是来自 Object[]不正确且未经检查的强制转换至E[] .

你明白我的意思吗?

关于java - 泛型和类型删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26391600/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com