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 的自动装箱有很多意想不到的结果,其中有些是广为人知的,这些奇怪的结果多数是 因为自动装箱对象的缓存导致的。
自动装箱拆箱 jdk.longaccumulator 计数器 jdk.threadlocal DateFormatService: 如何线程安全的使用 SimpleDateFormat jdk.volatilex VolatileArrays: volatile 例子 jdk.collection.union JDK: javaAPI 方式 ...
自动装箱与拆箱:自动装箱(Autoboxing)指的是自动地将基本数据类型转换为对应的包装类对象;自动拆箱(Unboxing)则是将包装类对象自动转换为基本数据类型。 常用方法:演示如何使用包装类中的这些常见方法。 null...
基本数据(Primitive)类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的(在这种情况下包装成为装箱,解包装称为拆箱)
OCJP认证-3期(PX017) 面向对象程序设计-Autoboxing.doc 学习资料 复习资料 教学资源
3.Java中的自动装箱和拆箱(Autoboxing and Unboxing) 4.Java中的注解处理器(Annotation Processing) 5.Java中的Lambda表达式和函数式接口 6.Java中的Optional类和null安全编程 7.Java中的并发集合...
jar包,官方版本,自测可用
jar包,官方版本,自测可用
jar包,官方版本,自测可用
jar包,官方版本,自测可用
本文将介绍J2SE5.0中三个比较重要的...这些特性包括范型(generics)的支持,枚举类型(enumeration)的支持,元数据(metadata)的支持,自动拆箱(unboxing)/装箱(autoboxing),可变个数参数(varargs),静态导入(staticimports),
It provides full coverage of all new features added since the previous edition, including generics, annotations, asserts, autoboxing, enums, for-each loops, variable arity methods, and static import ...
在API上做了很多的调整,已经删除了很多之前废弃的方法以及类,并支持了很多Java5 的新特性:包括泛型、可变参数、枚举和autoboxing等。 因此,此版本和2.x版本不能兼容,如要使用3.0版本,最好是在新项目中去使用,...
全面、准确、详尽地介绍了Java语言及其语法,论述了Java编译器所要检查的语法和Java运行模式的各个方面,同时还描述了Java语盲最重要的新特征(包括generics、annotationS、aSSertS、autoboxing、enumS、for-...
Java学习笔记 台湾 林信良 什么是Java 从autoboxing、unboxing认识对象 语法入门 Annotation 文本编辑器 Java SE6新功能简介 继承、多型
自动装箱和拆箱?autoboxing,unboxing 119 字符串相关类(String、 StringBuffer 、 StringBuilder) 120 String类的常用方法(已讲过,不再讲!) 120 StringBuffer和StringBuilder 121 String和StringBuffer和...
Enumerations, autoboxing, and annotations The I/O classes Generics Lambda expressions Modules String handling The Collections Framework Networking Event handling AWT Swing The Concurrent API The ...
java高手秘笈详细讲解了java底层的一点事 StringBuilder ...Autoboxing 和Unboxing vararge 可变参数 类型...数组名 Annotation @Override @Deprecated for/in 静态的import 格式化 Formatter Thread
It provides full coverage of all new features added in since the previous edition including generics, annotations, asserts, autoboxing, enums, for each loops, variable arity methods and static import...