为什么我们在Java中使用自动装箱和拆箱?
自动装箱是Java编译器在原始类型及其对应的对象包装器类之间进行的自动转换。例如,将int转换为Integer,将double转换为Double,依此类推。如果转换结果相反,则称为拆箱。
那么,为什么我们需要它?为什么要在Java中使用自动装箱和拆箱呢?
回答:
需要一些上下文来充分理解其背后的主要原因。
基元与类
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
。
以上是 为什么我们在Java中使用自动装箱和拆箱? 的全部内容, 来源链接: utcz.com/qa/433951.html