如何将双精度型添加到Integer的ArrayList中?(Java)

15 java generics arraylist

我试图了解如何将的Double值包含在ArrayListInteger。的numListArrayListInteger,并且从它的值是一个Double

这是代码:

package bounded.wildcards;

import java.util.ArrayList;
import java.util.List;

public class GenericsDemo {

    public static void main(String[] args) {
        // Invariance Workaround
        List<Integer> numList = new ArrayList<>();
        GenericsDemo.invarianceWorkaround(numList);
        System.out.println(numList);
    }

    static <T extends Number> void invarianceWorkaround(List<T> list) {

        T element = (T) new Double(23.3);  
        list.add(element);
    }

}
Run Code Online (Sandbox Code Playgroud)

这将编译并运行而不会出现错误。

Jir*_*sek 21

This is because of type erasure used with Java generics - the type checks are only performed at compile time for generic types, and the type info for generics is then erased, effectively turning List<Integer> into List<Object>.

My IDE warns you of an "Unchecked cast from Double to T". But the compiler couldn't be sure that your code is wrong, so it does not emit an error, just a warning.

Then at runtime, the type check is no longer present due to type erasure, so the code will run without error unless you perform some operation that fails due to incompatible runtime type. System.out.println() is not such operation.


If you change the print code to

Integer num = numList.get(0);
System.out.println(num);
Run Code Online (Sandbox Code Playgroud)

this will now involve runtime type check and will therefore fail:

java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer

  • 请注意,尝试执行此操作时会发出“ ClassCastException”:“ Integer i = numList.get(0)”。 (3认同)
  • @JiriTousek您可能对[Java is Unsound](https://hackernoon.com/java-is-unsound-28c84cb2b3f)感兴趣。基本上,所有Java编译器都会在位置添加强制类型检查以避免问题,因为它们知道类型系统已损坏。 (2认同)