变量如何以及何时强制转换为泛型类型参数中声明的类型?

安德烈(Andrei Rykhalski):
public static void main(String[] args) {

    List<Integer> integers = new ArrayList<>();
    integers.add(5); //element #0

    List list = integers;
    list.add("foo"); //element #1

    integers.get(1); //no error
    System.out.println(integers.get(1)); //no error, prints "foo"
    Integer i = integers.get(1); //throws ClassCastException

}

我试图理解转换类型变量的过程,声明为泛型类型参数,我有些困惑。因此,您可能会在我提供的示例中看到,在我们创建了一个非参数化的List,它引用了与相同的对象List<Integer>之后,我们可以将任何对象添加到该列表中(好的,在这里不足为奇),还有什么会引起混淆我是如此,我们可以从中提取非IntegerList<Integer> integers为什么ClassCastException在第一次或第二次呼叫时抛出integers.get(1)

我假设返回参数类型的方法实际上总是返回,Object并且那些返回的值在运行时隐式地尝试转换为l值类型或方法参数类型(因为在运行时没有泛型),但是以下测试使我确信:Integer始终比Object

public static void main(String[] args) {

    List<Integer> integers = new ArrayList<>();
    integers.add(5); //element #0

    List list = integers;
    list.add("foo"); //element #1

     print(integers.get(1));

}

private static void print(Object var) {
    System.out.println(var);
}

//this method is entered
private static void print(Integer var) { 
    System.out.println(var);
}

private static void print(String var) {
    System.out.println(var);
}

另一个有趣的事实是,尽管of ArrayList元素存储在Object[]数组中,但在方法中返回之前,它们始终会转换为type参数中定义的类型get()

public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}

E elementData(int index) {
    return (E) elementData[index];
}

因此,如果有人可以将我指向逐步解释这些问题的文档,我将非常感谢

保罗·波丁顿(Paul Boddington):

编译器在需要强制转换时插入强制转换。该方法System.out.println的参数类型为Object,因此不需要强制转换Integer为。

对于这三种print方法,将Integer选择具有类型参数的方法,因此编译器将插入强制类型转换。根据复杂的规则集,编译选择使用三种方法中的哪一种。这些规则使用通用信息来查看integers.get(1)具有type的信息Integer,因此Integer选择版本并需要进行强制转换。结果,代码或多或少地等同于Java 4代码

List integers = new ArrayList();
integers.add("foo");
integers.add(Integer.valueOf(5));  // No autoboxing in Java 4!
print((Integer) integers.get(1));  // Cast inserted by compiler

演员要(E)在你的问题的最后一部分实际上并没有在运行时做任何事,所以不会抛出ClassCastException只需要使代码编译即可。您正在告诉编译器,是的,您确定Object确实是一个E并且以后不会引起异常(尽管您通过混合原始类型和泛型类型将其颠倒了)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在C#中强制转换为任何类型的泛型

Python如何以及何时确定变量的数据类型?

ByteBuddy泛型方法返回强制转换为具体类型

强制转换为泛型类型时的Java警告

使用泛型将对象强制转换为其父类型

泛型类型接口强制转换为特定接口

如何将数字类型转换为泛型类型参数?

类型转换为泛型

在Java中强制转换为泛型类型不会引发ClassCastException吗?

以匿名类型作为泛型参数的泛型类型实例,如何正确转换回原始类型?

如何在Swift中向下转换/强制转换结构的泛型类型

如何强制泛型类型参数符合某个签名

如何强制Java接受相同类型的泛型参数

将泛型类型变量转换为字符串

在C#中强制转换泛型函数类型参数

如何允许可转换为指针的泛型类型参数化另一种可转换为指针的泛型类型?

在扩展上声明泛型类型参数

如何在Kotlin中的isAssignableFrom检查之后强制转换泛型类型?

如何将枚举泛型类型的变量转换为 int 并返回

如何在 Delphi 中将特定类型的变量转换为泛型 T?

如何以声明方式强制类型兼容?

如何访问F#中声明为泛型参数的类型的静态成员

Java泛型和强制转换泛型类型

当 T 定义为数组时,如何将对象数组强制转换/转换为泛型类型 T?

Kotlin强制将可为空的泛型类型转换为相同的泛型的不可为空类型?

如何将泛型类型转换为对象?

如何在Java中将泛型转换为具体类型

如何将泛型类型存储在缓存中,以避免检索时未经检查的强制类型转换?

如何在Java中动态声明实例的泛型类型