这不是什么是装箱和拆箱的问题,而是 为什么 Java和C#之类的语言需要这样做?
我对C ++,STL和Boost非常熟悉。
在C ++中,我可以很容易地编写这样的内容,
std::vector<double> dummy;
我对Java有一定的经验,但是我真的很惊讶,因为我不得不写这样的东西,
ArrayList<Double> dummy = new ArrayList<Double>();
我的问题是,为什么它应该是一个对象,在谈到泛型时在技术上很难包含原始类型?
在谈到泛型时,从技术上讲很难包括原始类型吗?
在Java的情况下,这是因为泛型的工作方式。在Java中,泛型是一种编译时技巧,可防止您将Image对象放入ArrayList<String>。但是,Java的泛型是通过类型擦除实现的:泛型类型信息在运行时会丢失。这是出于兼容性的原因,因为泛型是在Java生命后期才添加的。这意味着,在运行时,an ArrayList<String>实际上是一个ArrayList<Object>(或更好的:只是ArrayList期望并返回Object其所有方法)String在检索值时自动转换为。
Image
ArrayList<String>
ArrayList<Object>
ArrayList
Object
String
但是由于int不是从派生的Object,所以您不能将其放在期望的ArrayList中(在运行时)Object,也不能将强制Object转换int为。这意味着int必须将原语包装为确实继承自的类型Object,例如Integer。
int
Integer
例如,C#的工作原理有所不同。C#中的泛型也会在运行时强制执行,并且不需要装箱List<int>。仅当您尝试将值类型存储int在引用类型变量(如)中时,C#中的装箱操作才会发生object。由于int在C#中是从C#继承而来的Object,因此编写object obj = 2是完全有效的,但是int将被装箱,这是由编译器自动完成的(没有Integer引用类型暴露给用户或其他任何对象)。
List<int>
object
object obj = 2