- 浏览: 77113 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (95)
- Linux(CentOS) (17)
- ubuntu (16)
- linux命令 (13)
- java基础 (8)
- eclipse maven (1)
- ubuntu xen (0)
- samba (1)
- jdk (1)
- linux (1)
- jenkins (1)
- MySQL (4)
- spring (1)
- redis (2)
- zookeeper (3)
- java多线程 (3)
- 线程池 (2)
- 工具类 (1)
- 技术问答 (1)
- 算法 (1)
- eclipse JVM (1)
- hadoop配置 (2)
- hadoop配置 HDFS (0)
- ubuntu svn (1)
- hadoop (5)
- mapReduce (1)
- HDFS (2)
- hive (3)
- flume (1)
- python (6)
- centos (1)
- svn (1)
- sonar (1)
- JVM (1)
- kafka (1)
- zabbix (1)
- python paramiko (1)
- TPS (1)
- docker (4)
- ssh (2)
- Go (1)
最新评论
PS:基本转载于 http://blog.csdn.net/jairuschan/article/details/7513045
拆箱与装箱是相反的操作。装箱是将一个原始数据类型赋值给相应封装类的变量。而拆箱则是将一个封装类的变量赋值给相应原始数据类型的变量。
Java作为面向对象语言,有人认为所看到的都是对象,事实上,在Java SE 5之前,基本类型默认并不是采用对象存在的如果您想要把基本类型作为对象来处理,就必须自行转换。
#对象是不能直接进行运算的,要转化为基本数据类型后才能进行加减乘除
1、自动装箱
Integer i=3;
事实上调用的Integer.valueOf(int i);
2、自动拆箱
从上面的代码中,大家可看出integer100为一个Integer类型的引用,int100为一个int类型的原始数据类型。但是,我们可以将一个Integer类型的对象赋值给其相应原始数据类型的变量,这便是拆箱。
断点进行跟踪
也就是,jdk帮我们完成了对intValue()方法的调用。对于以上的实验而言,便是调用integer100的intValue()方法,将其返回值赋给了int100。
3、扩展
实验1
在以上代码的第三行中,integer400与int400执行了==运行。而这两个是不同类型的变量,到底是integer400拆箱了,还是int400装箱了呢?运行结果是什么呢?
==运算是判断两个对象的地址是否相等或者判断两个基础数据类型的值是否相等。所以,大家很容易推测到,如果integer400拆箱了,则说明对比的是两个基础类型的值,那此时必然相等,运行结果为true;如果int400装箱了,则说明对比的是两个对象的地址是否相等,那此时地址必然不相等,运行结果为false。(至于为什么笔者对它们赋值为400,就是后面将要讲到的陷阱有关)。
我们实际的运行结果为true。所以是integer400拆箱了。对代码跟踪的结果也证明这一点。
实验2
在以上代码的第三行中,integer100的方法equals的参数为int100。我们知道equals方法的参数为Object,而不是基础数据类型,因而在这里必然是int100装箱了。对代码跟踪的结果也证明了这一点。
其实,如果一个方法中参数类型为原始数据类型,所传入的参数类型为其封装类,则会自动对其进行拆箱;相应地,如果一个方法中参数类型为封装类型,所传入的参数类型为其原始数据类型,则会自动对其进行装箱。
实验3
第4行中,integer100+int100就会得到一个类型为int且value为200的基础数据类型b,再将b进行装箱得到o,执行这个对象的toString()方法,并输出”200”;
第5行中,integer100+int100就会得到一个类型为int且value为200的基础数据类型b1,==运算将long200进行拆箱得到b2,显然b1==b2,输出true;
第6行中,integer100+int100就会得到一个类型为int且value为200的基础数据类型b,Long的equals方法将b进行装箱,但装箱所得到的是类型为Integer的对象o,因为o与long200为不同的类型的对象,所以输出false;
程序运行的结果为:
4、陷阱
陷阱1
这两行代码是完全合法的,完全能够通过编译的,但是在运行时,就会抛出空指针异常。其中,integer100为Integer类型的对象,它当然可以指向null。但在第二行时,就会对integer100进行拆箱,也就是对一个null对象执行intValue()方法,当然会抛出空指针异常。所以,有拆箱操作时一定要特别注意封装类对象是否为null。
陷阱2
因为i1、i2、i3、i4都是Integer类型的,所以我们想,运行结果应该都是false。但是,真实的运行结果为“System.out.println(i1==i2);”为 true,但是“System.out.println(i3==i4);”为false。也就意味着,i1与i2这两个Integer类型的引用指向了同一个对象,而i3与i4指向了不同的对象。为什么呢?不都是调用Integer.valueOf(int i)方法吗?
让我们再看看Integer.valueOf(int i)方法。
我们可以看到当i>=-128且i<=IntegerCache.high时,直接返回IntegerCache.cache[i + 128]。其中,IntegerCache为Integer的内部静态类,其原码如下:
我们可以清楚地看到,IntegerCache有静态成员变量cache,为一个拥有256个元素的数组。在IntegerCache中也对cache进行了初始化,即第i个元素是值为i-128的Integer对象。而-128至127是最常用的Integer对象,这样的做法也在很大程度上提高了性能。也正因为如此,“Integeri1=100;Integer i2=100;”,i1与i2得到是相同的对象。
对比扩展中的第二个实验,我们得知,当封装类与基础类型进行==运行时,封装类会进行拆箱,拆箱结果与基础类型对比值;而两个封装类进行==运行时,与其它的对象进行==运行一样,对比两个对象的地址,也即判断是否两个引用是否指向同一个对象。
拆箱与装箱是相反的操作。装箱是将一个原始数据类型赋值给相应封装类的变量。而拆箱则是将一个封装类的变量赋值给相应原始数据类型的变量。
Java作为面向对象语言,有人认为所看到的都是对象,事实上,在Java SE 5之前,基本类型默认并不是采用对象存在的如果您想要把基本类型作为对象来处理,就必须自行转换。
#对象是不能直接进行运算的,要转化为基本数据类型后才能进行加减乘除
1、自动装箱
Integer i=3;
事实上调用的Integer.valueOf(int i);
2、自动拆箱
Integer integer100=100; int int100=integer100;
从上面的代码中,大家可看出integer100为一个Integer类型的引用,int100为一个int类型的原始数据类型。但是,我们可以将一个Integer类型的对象赋值给其相应原始数据类型的变量,这便是拆箱。
断点进行跟踪
/** * Returns the value of this <code>Integer</code> as an * <code>int</code>. */ public int intValue() { return value; }
也就是,jdk帮我们完成了对intValue()方法的调用。对于以上的实验而言,便是调用integer100的intValue()方法,将其返回值赋给了int100。
3、扩展
实验1
Integer integer400=400; int int400=400; System.out.println(integer400==int400);
在以上代码的第三行中,integer400与int400执行了==运行。而这两个是不同类型的变量,到底是integer400拆箱了,还是int400装箱了呢?运行结果是什么呢?
==运算是判断两个对象的地址是否相等或者判断两个基础数据类型的值是否相等。所以,大家很容易推测到,如果integer400拆箱了,则说明对比的是两个基础类型的值,那此时必然相等,运行结果为true;如果int400装箱了,则说明对比的是两个对象的地址是否相等,那此时地址必然不相等,运行结果为false。(至于为什么笔者对它们赋值为400,就是后面将要讲到的陷阱有关)。
我们实际的运行结果为true。所以是integer400拆箱了。对代码跟踪的结果也证明这一点。
实验2
Integer integer100=100; int int100=100; System.out.println(integer100.equals(int100));
在以上代码的第三行中,integer100的方法equals的参数为int100。我们知道equals方法的参数为Object,而不是基础数据类型,因而在这里必然是int100装箱了。对代码跟踪的结果也证明了这一点。
其实,如果一个方法中参数类型为原始数据类型,所传入的参数类型为其封装类,则会自动对其进行拆箱;相应地,如果一个方法中参数类型为封装类型,所传入的参数类型为其原始数据类型,则会自动对其进行装箱。
实验3
Integer integer100 = 100; int int100 = 100; Long long200 = 200l; System.out.println(integer100 + int100); System.out.println(long200 == (integer100 + int100)); System.out.println(long200.equals(integer100 + int100));
第4行中,integer100+int100就会得到一个类型为int且value为200的基础数据类型b,再将b进行装箱得到o,执行这个对象的toString()方法,并输出”200”;
第5行中,integer100+int100就会得到一个类型为int且value为200的基础数据类型b1,==运算将long200进行拆箱得到b2,显然b1==b2,输出true;
第6行中,integer100+int100就会得到一个类型为int且value为200的基础数据类型b,Long的equals方法将b进行装箱,但装箱所得到的是类型为Integer的对象o,因为o与long200为不同的类型的对象,所以输出false;
程序运行的结果为:
200 true false
4、陷阱
陷阱1
Integer integer100=null; int int100=integer100;
这两行代码是完全合法的,完全能够通过编译的,但是在运行时,就会抛出空指针异常。其中,integer100为Integer类型的对象,它当然可以指向null。但在第二行时,就会对integer100进行拆箱,也就是对一个null对象执行intValue()方法,当然会抛出空指针异常。所以,有拆箱操作时一定要特别注意封装类对象是否为null。
陷阱2
Integer i1=100; Integer i2=100; Integer i3=300; Integer i4=300; System.out.println(i1==i2); System.out.println(i3==i4);
因为i1、i2、i3、i4都是Integer类型的,所以我们想,运行结果应该都是false。但是,真实的运行结果为“System.out.println(i1==i2);”为 true,但是“System.out.println(i3==i4);”为false。也就意味着,i1与i2这两个Integer类型的引用指向了同一个对象,而i3与i4指向了不同的对象。为什么呢?不都是调用Integer.valueOf(int i)方法吗?
让我们再看看Integer.valueOf(int i)方法。
/** * Returns a <tt>Integer</tt> instance representing the specified * <tt>int</tt> value. * If a new <tt>Integer</tt> instance is not required, this method * should generally be used in preference to the constructor * {@link #Integer(int)}, as this method is likely to yield * significantly better space and time performance by caching * frequently requested values. * * @param i an <code>int</code> value. * @return a <tt>Integer</tt> instance representing <tt>i</tt>. * @since 1.5 */ public static Integer valueOf(int i) { if(i >= -128 && i <= IntegerCache.high) return IntegerCache.cache[i + 128]; else return new Integer(i); }
我们可以看到当i>=-128且i<=IntegerCache.high时,直接返回IntegerCache.cache[i + 128]。其中,IntegerCache为Integer的内部静态类,其原码如下:
private static class IntegerCache { static final int high; static final Integer cache[]; static { final int low = -128; // high value may be configured by property int h = 127; if (integerCacheHighPropValue != null) { // Use Long.decode here to avoid invoking methods that // require Integer's autoboxing cache to be initialized int i = Long.decode(integerCacheHighPropValue).intValue(); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - -low); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} }
我们可以清楚地看到,IntegerCache有静态成员变量cache,为一个拥有256个元素的数组。在IntegerCache中也对cache进行了初始化,即第i个元素是值为i-128的Integer对象。而-128至127是最常用的Integer对象,这样的做法也在很大程度上提高了性能。也正因为如此,“Integeri1=100;Integer i2=100;”,i1与i2得到是相同的对象。
对比扩展中的第二个实验,我们得知,当封装类与基础类型进行==运行时,封装类会进行拆箱,拆箱结果与基础类型对比值;而两个封装类进行==运行时,与其它的对象进行==运行一样,对比两个对象的地址,也即判断是否两个引用是否指向同一个对象。
发表评论
-
数组中最大和的子数组
2014-12-18 19:49 533public static void main ... -
泛型复习
2014-10-19 16:29 329绕过编译器加入其他类型 import java.util. ... -
Hash内存溢出问题
2014-10-19 11:30 469public class Student { p ... -
Java数组操作的10大方法
2014-08-28 15:36 4490、定义一个Java数组 String[] aArray ... -
JVM系列一
2014-07-04 21:52 0当JVM运行Java程序的时候,它会加载对应的class文件, ... -
java的反射和代理实现IOC模式 模拟spring
2014-07-03 16:59 669转自http://blog.csdn.net/wwww1988 ... -
java在一个循环中删除列表中元素的问题
2014-07-01 11:39 479思考下面这段代码的结果: ArrayList<Str ... -
array与list相关
2014-07-01 11:17 6061、将数组转化为一个列表 List<String&g ...
相关推荐
本篇文章主要介绍了详解Java 自动装箱与拆箱的实现原理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
自动装箱与拆箱的机制可以让我们在Java的变量赋值或者是方法调用等情况下使用原始类型或者对象类型更加简单直接。 如果你在Java1.5下进行过编程的话,你一定不会陌生这一点,你不能直接地向集合(Collections)中放...
下面小编就为大家带来一篇浅谈Java自动装箱与拆箱及其陷阱。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
Java中的自动装箱与拆箱Java开发Java经验技巧共6页.pdf.zip
Java中的自动装箱与拆箱_.docx
Tedu正则表达式与Object与自动装箱与拆箱。
自动装箱与拆箱:自动装箱(Autoboxing)指的是自动地将基本数据类型转换为对应的包装类对象;自动拆箱(Unboxing)则是将包装类对象自动转换为基本数据类型。 常用方法:演示如何使用包装类中的这些常见方法。 null...
代码中,我们可以看到自动装箱和拆箱的例子。在自动装箱中,我们将基本类型 int 赋值给 Integer 对象,而在自动拆箱中,我们将 Double 对象赋值给基本类型 double。这样,我们可以直接使用基本类型和包装类型之间的...
主要给大家介绍了关于Java中自动装箱、拆箱引起的耗时的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
什么是自动装箱和自动拆箱
自动装箱和拆箱问题是Java中一个老生常谈的问题了,我们来一些看一下装箱和拆箱中的若干问题。本文先讲述装箱和拆箱基本的东西,再来看一下面试笔试中经常遇到的与装箱、拆箱相关的问题。 以下是本文的目录大纲:...
基本数据(Primitive)类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的(在这种情况下包装成为装箱,解包装称为拆箱)
学C++的时候,不管是什么操作,基本上都可以知道编译器到底干了啥。... 第二个则对应与x++,先取出x的引用ALOAD 1:x,接着调用intValue方法得到值,然后压栈,+1,再调用valueOf进行装箱操作,这样x的值完成了++
《深入理解java虚拟机》自动装箱拆箱实例.doc
1. 自动装箱: 2. 自动拆箱: 3. 缓存问题
6.Java自动装箱与拆箱 7.重载和重写的区别 8.equals与==的区别 9.Hashcode的作用 10.String、String StringBuffer 和 StringBuilder 的区别是什 么? 11.ArrayList和linkedList的区别 12.HashMap和HashTable的区别 13...
计算机后端-Java-Java核心基础-第14章 面向对象06 24. 新特性:自动装箱与自动拆箱.avi
//这里就是自动的装箱,将3转换成Integer类型并放到集合中自动拆箱包装类自动转为基本类型 Integer >> int面试常见题目:自动拆箱与自动装箱的问
主要介绍了java编程中自动拆箱与自动装箱详解,具有一定参考价值,需要的朋友可以了解下。
BankingApplication:自动装箱,拆箱,包装器概念