列出<! - ? - >,整数转换为List <double>,为什么可能?</double>

时间:2014-04-24 20:02:25

标签: java arraylist casting integer double

我创建了列表
private final List<Double> prices
我有方法:

public Double getPrice(int i)
{
    i--;
    if (i >= this.prices.size())
    {
        return Double.NEGATIVE_INFINITY;
    }
    return this.prices.get(i);
}

看起来不错......但总是会抛出:
ClassCastException: java.lang.Integer cannot be cast to java.lang.Double


经过一些测试后我发现:
我从配置创建这个列表,但在配置中我使用没有点的数字,所以代码创建列表,整数不是双打(内部有整数的ArrayList)
但为什么我可以将此列表强制转换为List而没有任何错误? 例如:

Integer a = 1;
Integer b = 1;
Integer c = 1;
Integer d = 1;
List<?> listI = new ArrayList<>(Arrays.asList(a, b, c, d));
List<Double> listD = (List<Double>) listI;
for (Object o : listD)
{
        System.out.println(o.getClass().getSimpleName()); // Integer
}
System.out.println("done");

此代码没有任何错误,但是从Double列表中打印Integer,为什么不在ClassCastException中抛出List<Double> listD = (List<Double>) listI;? 因此,如果您尝试添加double num = listD.get(0);,请抛出ClassCastException

2 个答案:

答案 0 :(得分:2)

Java调用Arrays.asList时推断的泛型类型参数是asList - Integer的参数的常见类型,因此新的ArrayList是一个ArrayList<Integer>,而不是ArrayList<Double>

Java不会在ClassCastException抛出List<Double> listD = (List<Double>) listI;,因为在运行时,类型擦除已经发生,而对于JVM,代码如下所示:

List listD = (List) listI;

这对JVM来说非常好。

ClassCastException稍后出现,尝试将真正来自列表的Integer转换为Double。对于泛型,Java编译器将在检索项目时向泛型类型参数(在本例中为Double)插入隐式强制转换。但是,它确实是Integer

在编译此代码时,应该在演员表上发出关于&#34;未经检查的演员&#34;的警告。将List<?>投射到List<Double>时。它警告你,你已经证明了这种可能性 - 以后可能ClassCastException

答案 1 :(得分:1)

  

为什么不在List<Double> listD = (List<Double>) listI;中抛出ClassCastException?

在运行时,所有类型信息都会丢失。您将原始类型与参数化类型混合,这就是您在运行时遇到麻烦的原因。

试试这个

    List<Integer> listI = new ArrayList<Integer>(Arrays.asList(a, b, c, d));
    List<Double> listD = (List<Double>) listI; // compilation error
                                // Cannot cast from List<Integer> to List<Double>

示例代码:

    // Here's a basic parameterized list.
List<Integer> li = new ArrayList<Integer>();

    // It is legal to assign a parameterized type to a nonparameterized variable
List l = li;

    // This line is a bug, but it compiles and runs.
    // The Java 5.0 compiler will issue an unchecked warning about it.
    // If it appeared as part of a legacy class compiled with Java 1.4, however,
    // then we'd never even get the warning.
l.add("hello");

    // This line compiles without warning but throws ClassCastException at runtime.
    // Note that the failure can occur far away from the actual bug.
Integer i = li.get(0);

有关更多示例代码,请查看Generic Types, Part 1 - O'Reilly Media