需要一些上下文来充分理解其背后的主要原因。
基元与类
Java中的原始变量包含值(整数,双精度浮点二进制数等)。由于这些值的长度可能不同,因此包含它们的变量的长度也可能不同(请考虑
float与
double)。
另一方面,类变量包含对实例的引用。引用通常在许多语言中实现为指针(或与指针非常相似的东西)。这些东西通常具有相同的大小,而不管它们指的是(实例的大小
Object,String,Integer,等)。
类变量的此属性使它们包含的引用可以互换(一定程度上)。这使我们能够执行所谓的替换:广义上讲,是将特定类型的实例用作另一种相关类型的实例(例如,将
a String用作
Object)。
原始变量不能以相同的方式互换,彼此之间也不能互换
Object。最明显的原因(但不是唯一原因)是它们的大小差异。这使得原始类型在这方面不方便,但是我们仍然需要该语言中的它们(由于主要归结为性能的原因)。
泛型和类型擦除
泛型类型是具有一个或多个类型参数的类型(确切的数字称为泛型arity)。例如,通用类型定义
List<T>具有类型参数T,可以是Object(产生具体类型
List<Object>),
String(List<String>),Integer(List<Integer>)等。
泛型类型比非泛型类型复杂得多。当他们被介绍到Java(首次发行)之后,为了避免到JVM根本变化,并与旧的二进制可能破坏兼容性,Java的创作者决定在最小侵入性的方式来实现泛型类型:所有的具体类型
List<T>实际上,已被编译为(的二进制等效项)
List<Object>(对于其他类型,边界可能不是Object,但你明白了)。泛型和类型参数信息在此过程中丢失,这就是为什么我们将其称为类型擦除。
将两者放在一起
现在的问题是上述现实的结合:如果在所有情况下都
List<T>变为
List<Object>,则T必须始终是可以直接分配给的类型Object。不允许其他任何事情。因为,正如我们之前所说,int,float并且double不与互换Object,不能有一个
List<int>,List<float>或
List<double>(除非仿制药的显著更复杂的实现JVM中的存在)。
但是Java提供喜欢的类型
Integer,
Float以及
Double其在类实例包装这些原语,使他们有效地作为替代Object,从而使泛型类型与原语间接地工作,以及(因为你可以有
List<Integer>,List<Float>,List<Double>等)。
创建的过程
Integer,从一个
int,一
个Float从
float等,被称为拳击。相反的称为拆箱。因为每次使用原始语言都必须对原始语言进行装箱Object是很不方便的,所以在某些情况下该语言会自动执行此操作- 这称为
autoboxing。



