运行时泛型 [英] Generics at Runtime

查看:53
本文介绍了运行时泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有两个程序第一个代码为什么起作用?我希望它在添加String而不是Integer时访问元素时抛出运行时异常

There two programs Why is the first code code working?I expected it to throw a Run time Exception while accessing the elements as String is added instead of Integer

类似地..第二个代码访问元素时抛出了运行时异常,尽管尽管声明它可以容纳String,但是它可以舒适地在arrayList中添加Integer.

Similarly.. The second code is throwing Run time Exception while accessing the element though it is able to add Integer in the arrayList comfortably despite declaring it to hold String.

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

In both the codes,We are successful in adding the different Data types,but the problems seems to appear while accessing elements

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);

    }
}

推荐答案

由于

You can add elements in both cases due to type erasure. At run time, the class doesn't know it was declared as new ArrayList<String>(), just that it was declared as new ArrayList().

println 情况下,该方法的编译时重载分辨率起作用. System.out PrintStream ,它对 println 具有多个重载.其中包括:

In the println case, the method's compile-time overload resolution comes into play. System.out is a PrintStream, which has several overloads for println. Among these are:

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

Java编译器将选择最具体的那个.在 ArrayList< Integer> 情况下,它是第一个,在 ArrayList< String> 情况下,它是第二个.完成此操作后,作为类型擦除处理的一部分,它将把原始 ArrayList :: get(int)调用的Object结果强制转换为所需的类型,但前提是该强制转换是必需的.

The Java compiler will pick whichever of those is most specific. In the ArrayList<Integer> case it's the first one, and in the ArrayList<String> case it's the second. Once it does that, as part of the type erasure handling, it will cast the Object result of the raw ArrayList::get(int) call to the required type, but only if that cast is necessary.

对于 ArrayList< Integer> 调用,不需要强制转换( ArrayList :: get(int)返回一个Object,这正是方法期望),因此javac忽略了它.在 ArrayList< String> 调用的情况下,它 是必需的,因此javac添加了它.您所看到的:

In the case of the ArrayList<Integer> call, the cast is not necessary (ArrayList::get(int) returns an Object, which is exactly what the method expects), so javac omits it. In the case of the ArrayList<String> call, it is necessary, so javac adds it. What you see as:

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

实际上被编译为:

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

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

But the element isn't a String, and that's what results in the ClassCastException.

这篇关于运行时泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆