As any Java programmer knows, you can’t put an int (or other primitive value) into a collection. Collections can only hold object references, so you have to box primitive values into the appropriate wrapper class (which is Integer in the case of int). When you take the object out of the collection, you get the Integer that you put in; if you need an int, you must unbox the Integer using the intValue method. All of this boxing and unboxing is a pain, and clutters up your code. The autoboxing and unboxing feature automates the process, eliminating the pain and the clutter.
每个Java程序员都知道,不可能把一个int(或其它基本类型的值)放入一个collection中去。集合只能存放对象的引用,所以您必须把基本类型值装箱成适合的包装类(int对应的包装类是integer)。当您想从集合中取出对象时,您获取的是您放入的Integer;如果您需要的是一个int,您就必须用intValue方法。装箱出箱是一件很痛苦的事情,也把代码弄得乱糟糟的。自动装箱出箱特性使这一过程变得自动化,消除这种痛苦,并可以保持代码整洁。
The following example illustrates autoboxing and unboxing, along with generics and the for-each loop. In a mere ten lines of code, it computes and prints an alphabetized frequency table of the words appearing on the command line.
下面的例子演示了自动装箱和出箱,同时也用到了范型和for-each循环。在仅有的十行代码中,计算并按字母顺序打印出命令行中每个单词的出现频率。
import java.util.*;
// Prints a frequency table of the words on the command line
public class Frequency {
public static void main(String[] args) {
Map<String, Integer> m = new TreeMap<String, Integer>();
for (String word : args) {
Integer freq = m.get(word);
m.put(word, (freq == null ? 1 : freq + 1));
}
System.out.println(m);
}
}
java Frequency if it is to be it is up to me to do the watusi
{be=1, do=1, if=1, is=2, it=2, me=1, the=1, to=3, up=1, watusi=1}
The program first declares a map from String to Integer, associating the number of times a word occurs on the command line with the word. Then it iterates over each word on the command line. For each word, it looks up the word in the map. Then it puts a revised entry for the word into the map. The line that does this (highlighted in green) contains both autoboxing and unboxing. To compute the new value to associate with the word, first it looks at the current value (freq). If it is null, this is the first occurrence of the word, so it puts 1 into the map. Otherwise, it adds 1 to the number of prior occurrences and puts that value into the map. But of course you cannot put an int into a map, nor can you add one to an Integer. What is really happening is this: In order to add 1 to freq, it is automatically unboxed, resulting in an expression of type int. Since both of the alternative expressions in the conditional expression are of type int, so too is the conditional expression itself. In order to put this int value into the map, it is automatically boxed into an Integer.
程序首先声明一个String到Integer的map来关联命令行中每个单词出现在次数。然后遍历每个单词。程序在map中查找每个单词,然后把修改过的entry放入map中。绿色高亮显示的代码既包含自动装箱又包含自动出箱。为了计算与每个单词相关联的新值,首先程序查看当前值,如果它是null的话,此时是该单词第一次出现的情况,在map中放入1。否则就在前次出现的次数基础上加1,然后再放到map中去。当然,您既可能把int放入map中,也不可能把1加到Integer上去。到底发生了什么呢?为了使freq加1,程序自动进行出箱,产生一个int类型的表达式。因为在条件表达式两边都是int类型,条件表达式自身也当然是。为了能把int类型值放入map,程序自动地把它装箱成Integer。
The result of all this magic is that you can largely ignore the distinction between int and Integer, with a few caveats. An Integer expression can have a null value. If your program tries to autounbox null, it will throw a NullPointerException. The == operator performs reference identity comparisons on Integer expressions and value equality comparisons on int expressions. Finally, there are performance costs associated with boxing and unboxing, even if it is done automatically.
这样您就可以忽略int与Integer间的区分,只是会有一些警告。整型可包含null值。如果您的程序试图把一个null值出箱,就会抛出一个NullPointerException异常。对于Integer类型==操作符进行引用的比较,而对于int类型,进行值的比较。最后要提一下,即使装箱出箱是自动完成的,也是有很大的性能损耗的。
Here is another sample program featuring autoboxing and unboxing. It is a static factory that takes an int array and returns a List of Integer backed by the array. In a mere ten lines of code this method provides the full richness of the List interface atop an int array. All changes to the list write through to the array and vice-versa. The lines that use autoboxing or unboxing are highlighted in green:
这里还有一个用到装箱出箱的程序。接收一个int类型数组并返回Integer类型链表。在十几行代码中,这个方法提供从数组到链表的丰富内容。绿色高亮部分是装箱出箱:
// List adapter for primitive int array
public static List<Integer> asList(final int[] a) {
return new AbstractList<Integer>() {
public Integer get(int i) { return a[i]; }
// Throws NullPointerException if val == null
public Integer set(int i, Integer val) {
Integer oldVal = a[i];
a[i] = val;
return oldVal;
}
public int size() { return a.length; }
};
}
The performance of the resulting list is likely to be poor, as it boxes or unboxes on every get or set operation. It is plenty fast enough for occasional use, but it would be folly to use it in a performance critical inner loop.
结果链表的性能可能是很差的,因为每一个get或set操作都执行了出箱或装箱。对于间歇性的使用它是足够快的,但在内循环中会严重影响性能。
So when should you use autoboxing and unboxing? Use them only when there is an “impedance mismatch” between reference types and primitives, for example, when you have to put numerical values into a collection. It is not appropriate to use autoboxing and unboxing for scientific computing, or other performance-sensitive numerical code. An Integer is not a substitute for an int; autoboxing and unboxing blur the distinction between primitive types and reference types, but they do not eliminate it.
那什么时候该使用自动装箱和出箱呢?仅在引用类型和基本型间出现了“类型不匹配”错误时才用,例如,当您必须把一个数值型放入一个集合中去时。在使用科学计数法或其它敏感性数字代码中不宜使用自动装箱和出箱。Integer并不是int的替代品;自动装箱和出箱使基本型和引用类型间的区别变得模糊起来,但并没有消除。
分享到:
相关推荐
Java的自动装箱功能极大地简化了基本数据类型与它们对应的包装类之间的相互转换。然而,这一特性可能会引起一些不易察觉的副作用,这些副作用往往是由于JVM对某些包装类对象实现了缓存机制所致。 1. ==和equals行为...
在Java编程语言中,自动装箱(Autoboxing)和自动拆箱(Unboxing)是两个重要的特性,它们简化了基本类型(如int、double等)与对应的包装类(如Integer、Double等)之间的转换过程。这些特性是在Java 5引入的,极大...
在Java编程中,自动装箱(Autoboxing)和自动拆箱(Unboxing)是两个非常核心的概念,它们允许基本数据类型和它们对应的包装类之间无缝转换。这种转换机制在Java 5中引入,极大地简化了代码编写,但同时也带来了一些...
在Java中,自动装箱(Autoboxing)和拆箱(Unboxing)是Java编译器提供的一种特性,用于在基本数据类型和对应的包装类之间进行自动转换。这种特性简化了编程过程中的类型转换操作,使得代码更为简洁易读。 **自动...
在Java编程语言中,自动装箱(Autoboxing)和自动拆箱(Unboxing)是从Java 1.5版本开始引入的一项特性,其目的是简化原始类型(Primitive Types)与它们对应的包装类(Wrapper Classes)之间的转换过程。...
自动装箱拆箱 jdk.longaccumulator 计数器 jdk.threadlocal DateFormatService: 如何线程安全的使用 SimpleDateFormat jdk.volatilex VolatileArrays: volatile 例子 jdk.collection.union JDK: javaAPI 方式 ...
1. 基本数据类型的自动装箱(Autoboxing) 自动装箱是指将基本数据类型(primitive type)转换为对应的包装器类型(wrapper class)。例如,int类型可以自动转换为Integer类型,double类型可以自动转换为Double类型...
自动装箱与拆箱:自动装箱(Autoboxing)指的是自动地将基本数据类型转换为对应的包装类对象;自动拆箱(Unboxing)则是将包装类对象自动转换为基本数据类型。 常用方法:演示如何使用包装类中的这些常见方法。 null...
面向对象程序设计是Java编程的核心,而Autoboxing(自动装箱)是Java SE 5.0引入的一个重要特性,它极大地简化了基本数据类型与它们对应的包装类之间的转换过程。在Java中,每个基本数据类型都有一个对应的包装类,...
本篇文章将从J2SE5.0新增的自动装箱(Autoboxing)与拆箱(Unboxing)功能入手,探讨它们在Java编程中的作用及其背后的原理。这一特性不仅简化了基本数据类型与包装类之间的转换,而且深刻体现了Java语言在面向对象...
自动装箱(Autoboxing)是Java 5引入的一个特性,它允许我们将基本数据类型(如int、double、char等)自动转换为对应的包装器类对象(如Integer、Double、Character)。例如,当我们试图将一个int值放入只能存储...
**自动装箱(Autoboxing)** 自动装箱是指编译器自动将基本数据类型(如int、char、boolean等)转换为它们对应的包装类(如Integer、Character、Boolean等)的过程。在Java中,这是为了提供对对象操作的便利,因为...
1. **自动装箱(Autoboxing)** 自动装箱是指将基本数据类型(如int、char、boolean等)自动转换为对应的包装器类对象(如Integer、Character、Boolean)。在JDK 6及以后的版本中,这一特性使得开发者可以更方便地...
这些新特性包括泛型(Generics)、增强的“for”循环(Enhanced For loop)、自动装箱/拆箱(Autoboxing/Unboxing)、类型安全的枚举(Typesafe enums)、静态导入(Static import)以及元数据(Metadata)。...
### 自动装箱与拆箱(Autoboxing and Unboxing) 自动装箱和拆箱是Java 1.5引入的另一个便利特性,它自动地在原始类型和对应的包装类之间进行转换。例如,我们可以直接将一个`int`赋值给`Integer`,反之亦然: ```...
自动装箱(Autoboxing)是Java的一个特性,将基本数据类型转换为对应的包装类。在循环或使用HashMap等容器时,自动装箱会导致额外的内存开销和性能损失。因此,应避免不必要的自动装箱,特别是在性能敏感的代码段中...
首先,自动装箱(AutoBoxing)和拆箱(Unboxing)是Java 5.0引入的一项新特性,它简化了基本类型与对应的包装器类型之间的转换。例如,你可以直接将一个int类型的值赋给Integer类型的变量,反之亦然。这样就避免了手动...
自动装箱(autoboxing)是Java 5引入的一个特性,它允许我们将基本数据类型自动转换为对应的包装类对象。反之,自动拆箱(unboxing)是将包装类对象转换回基本数据类型的过程。例如: ```java Integer i = 10; //...
自动装箱和拆箱允许在基本类型和它们对应的包装类之间进行无缝转换。例如,以前我们需要手动进行类型转换: ```java double d = 10.0; Double boxedD = new Double(d); ``` 在 JDK 1.5 后,自动装箱和拆箱使得这个...
4. 自动装箱与拆箱(Autoboxing and Unboxing): 自动装箱是指将基本数据类型转换为其对应的包装类对象,反之为自动拆箱。在JDK 1.5中,Java引入了这个特性,使得基础类型与包装类型之间的转换更加方便。例如,`...