为什么我们在Java中使用自动装箱和拆箱? [英] Why do we use autoboxing and unboxing in Java?

查看:248
本文介绍了为什么我们在Java中使用自动装箱和拆箱?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


Autoboxing是Java编译器在原始类型和它们对应的对象包装器
类之间产生
的自动转换。例如,将int转换为Integer,将double转换为
Double,依此类推。如果转换是另一种方式,这是
称为拆箱。

Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing.

那么我们为什么需要它呢?为什么我们需要它在Java中使用自动装箱和拆箱?

So why do we need it and why do we use autoboxing and unboxing in Java?

推荐答案

需要一些上下文才能完全理解这背后的主要原因。

Some context is required to fully understand the main reason behind this.

Java中的原始变量包含值(整数,双精度浮点数)点二进制数等)。由于这些值可能具有不同的长度,因此包含它们的变量可能也有不同的长度(考虑浮动)。

Primitive variables in Java contain values (an integer, a double-precision floating point binary number, etc). Because these values may have different lengths, the variables containing them may also have different lengths (consider float versus double).

另一方面,类变量包含对实例的引用。引用通常在许多语言中实现为指针(或与指针非常相似的东西)。这些东西通常具有相同的大小,无论它们引用的实例的大小如何( Object String 整数等。)

On the other hand, class variables contain references to instances. References are typically implemented as pointers (or something very similar to pointers) in many languages. These things typically have the same size, regardless of the sizes of the instances they refer to (Object, String, Integer, etc).

类变量的这个属性使它们包含的引用可以互换 (在一定程度上)。这使我们可以做我们所谓的替换:从广义上讲, 使用特定类型的实例作为另一个相关类型的实例 (使用字符串作为对象,例如)。

This property of class variables makes the references they contain interchangeable (to an extent). This allows us to do what we call substitution: broadly speaking, to use an instance of a particular type as an instance of another, related type (use a String as an Object, for example).

原始变量不可互换以相同的方式,彼此之间,也不是对象。最明显的原因(但不是唯一的原因)是它们的尺寸差异。这使原始类型在这方面不方便,但我们仍然需要它们的语言(原因主要归结为性能)。

Primitive variables aren't interchangeable in the same way, neither with each other, nor with Object. The most obvious reason for this (but not the only reason) is their size difference. This makes primitive types inconvenient in this respect, but we still need them in the language (for reasons that mainly boil down to performance).

通用类型是具有一个或多个类型参数的类型(确切的数字称为 generic arity )。例如,泛型类型定义 列表< T> 的类型参数 T ,可以是对象(生成具体类型 列表<对象> ),字符串列表< String> ),整数 List< Integer> )等等。

Generic types are types with one or more type parameters (the exact number is called generic arity). For example, the generic type definition List<T> has a type parameter T, which can be Object (producing a concrete type List<Object>), String (List<String>), Integer (List<Integer>) and so on.

通用类型比非通用类型复杂得多。当它们被引入Java(在其初始发布之后)时,为了避免对JVM进行彻底的更改并可能破坏与旧二进制文件的兼容性, Java的创建者决定以最少侵入性的方式实现泛型类型: / strong>所有具体类型的 List< T> 实际上编译为(二进制等价物) List< Object> (对于其他类型,绑定可能不是 Object ,但你明白了)。 通用arity和类型参数信息在此过程中丢失,这就是我们称之为 类型擦除

Generic types are a lot more complicated than non-generic ones. When they were introduced to Java (after its initial release), in order to avoid making radical changes to the JVM and possibly breaking compatibility with older binaries, the creators of Java decided to implement generic types in the least invasive way: all concrete types of List<T> are, in fact, compiled to (the binary equivalent of) List<Object> (for other types, the bound may be something other than Object, but you get the point). Generic arity and type parameter information are lost in this process, which is why we call it type erasure.

现在问题是上述现实的组合:如果 List< T> 变为 List< Object> 在所有情况下, T 必须始终是可以直接分配给对象的类型 即可。其他任何东西都不允许。因为,正如我们之前所说, int float double 不能与 Object 互换,不能有 List< int> List< float> List< double> (除非JVM中存在明显更复杂的泛型实现)。

Now the problem is the combination of the above realities: if List<T> becomes List<Object> in all cases, then T must always be a type that can be directly assigned to Object. Anything else can't be allowed. Since, as we said before, int, float and double aren't interchangeable with Object, there can't be a List<int>, List<float> or List<double> (unless a significantly more complicated implementation of generics existed in the JVM).

但Java提供的类型如 Integer Float Double 将这些基元包装在类实例中,使它们可以有效地替换为 Object ,从而允许泛型类型间接使用基元(因为你可以 列表<整数> 列表< Float> 列表< Double> 等等。)

But Java offers types like Integer, Float and Double which wrap these primitives in class instances, making them effectively substitutable as Object, thus allowing generic types to indirectly work with the primitives as well (because you can have List<Integer>, List<Float>, List<Double> and so on).

创建<$ c $的过程c> int 中的整数,来自 Float float 等等,被称为 拳击 。反向称为拆箱。因为每次要将它们用作对象时必须使用原始文件是不方便的,有时语言会自动执行此操作 - 这称为 autoboxing

The process of creating an Integer from an int, a Float from a float and so on, is called boxing. The reverse is called unboxing. Because having to box primitives every time you want to use them as Object is inconvenient, there are cases where the language does this automatically - that's called autoboxing.

这篇关于为什么我们在Java中使用自动装箱和拆箱?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆