java - 运行时的泛型

标签 java generics

有两个程序 为什么第一个代码有效?我希望它在访问元素时抛出运行时异常,因为添加了字符串而不是整数

同样.. 第二个代码在访问元素时抛出运行时异常,尽管它能够轻松地在 arrayList 中添加 Integer,尽管声明它保存 String。

在这两段代码中,我们都成功添加了不同的数据类型,但是在访问元素时似乎出现了问题

import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {

        ArrayList<Integer> arrayList = new ArrayList<>();
        Test.addToList(arrayList);

        System.out.println(arrayList.get(0));
    }

    public static void addToList(ArrayList arrayList) {
        arrayList.add("i");

    }
}






import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {

        ArrayList<String> arrayList = new ArrayList<>();
        Test.addToList(arrayList);

        System.out.println(arrayList.get(0));
    }

    public static void addToList(ArrayList arrayList) {
        arrayList.add(1);

    }
}

最佳答案

由于type erasure,您可以在这两种情况下添加元素。在运行时,该类不知道它被声明为 new ArrayList<String>() ,只是它被声明为 new ArrayList() .

println在这种情况下,该方法的编译时重载决策就会发挥作用。 System.outPrintStream ,其中有几个重载 println 。其中包括:

...
void println(Object x);
void println(String x);

Java 编译器将选择其中最具体的一个。在 ArrayList<Integer>情况是第一个,在 ArrayList<String> 中情况是第二种。一旦完成此操作,作为类型删除处理的一部分,它将强制转换原始 ArrayList::get(int) 的对象结果。调用所需的类型,但前提是需要进行强制转换。

ArrayList<Integer>为例调用时,强制转换是不必要的( ArrayList::get(int) 返回一个对象,这正是该方法所期望的),因此 javac 省略了它。以ArrayList<String>为例call,它必需的,所以javac添加了它。您所看到的:

System.out.println(arrayList.get(0));

实际上编译为:

System.out.println((String) arrayList.get(0));

但是该元素不是字符串,这就是导致 ClassCastException 的原因。

关于java - 运行时的泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41439041/

相关文章:

java - 无法使用 LIKE 从 PostgreSQL 选择 Unicode 数据

java - : T[] b = (T[]) new Object[n]; 的问题

java - 为什么我们可以使用具有泛型引用的数组

c# - 拦截通过 DynamicProxy 返回通用 Task<> 的异步方法

c# - "where T : class, new()"是什么意思?

java - 多线程程序在不同操作系统中的行为

java - 我似乎无法识别 Android 上的触摸事件

java - 如何在 Java 中使用自定义注释传递字符串和对象

generics - 具有通用参数类型的函数

java - 读取文件输入; nextLine() 不起作用