关键词:
在面试过程中,常常会有面试官问到基础的问题的时候都会问到Java的拆装箱,关于这个问题其实不是很难,但是如果平时进行自学的时候不是注意,就可能一脸懵逼,所以笔者就这个问题进行一些总结,共同促进!
一、拆装箱概念
所谓的拆装箱,就是自从JDK1.5之后,java的基本类型和引用类型之间的相互转换。
1.1拆箱
拆箱就是把Long,Integer,Double,Float 等将基本数据类型的首字母大写的相应的引用类型转化为基本数据类型的动作就叫拆箱。
1.2装箱
装箱就是把byte ,int ,short, long ,double,float,boolean,char 这些Java的基本数据类型在定义数据类型时不声明为相对应的引用类型,在编译器的处理下自动转化为引用类型的动作就叫做装箱。
二、拆装箱的相关应用
在JDK1.5后,当我们进行基本类型和引用类型的转换的时候就会方便:
package com.hzp.CZX; /** * 测试拆装箱 * @author 夜孤寒 * @version 1.1.1 */ public class TestDemo { /** * 拆装箱JDK1.5后 */ public static void first(){ Integer i=7;//基本类型-->引用类型 int j=i;//引用类型-->基本类型 System.out.println(j); } /** * 拆装箱JDK1.4 */ public static void second(){ Integer i=new Integer(78); int j=i.intValue(); System.out.println(j); } /** * 测试方法 * @param args */ public static void main(String[] args) { first(); second(); } }
上面介绍了关于拆装箱的一些基本点和使用方式,但是要使用拆装箱的话还有一些注意点需要注意,下面将这些注意点进行一些总结。
三、注意点
首先贴一段代码如下:
package com.ygh.CZX; /** * 关于java的拆装箱范围剖析 * @author 夜孤寒 * @version 1.1.1 */ public class Test { /** * 以Integer类型为例 */ public static void first(){ Integer i=new Integer(124); Integer j=new Integer(124); System.out.println(i==j);//false Integer a1=-128; Integer a2=-128; System.out.println(a1==a2);//true Integer b1=-129; Integer b2=-129; System.out.println(b1==b2);//false Integer c1=127; Integer c2=127; System.out.println(c1==c2);//true Integer d1=128; Integer d2=128; System.out.println(d1==d2);//false } public static void main(String[] args) { first(); } }
简单解释一下:
第一个结果为false的原因是因为创建了不同的对象,所以两者不一样;
但是第二个和第三个的结果为什么不一样?
下面贴出关于Integer类的源码,从源码的角度来分析这个问题:
/** * Returns an {@code Integer} instance representing the specified * {@code int} value. If a new {@code Integer} 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. * * This method will always cache values in the range -128 to 127, * inclusive, and may cache other values outside of this range. * * @param i an {@code int} value. * @return an {@code Integer} instance representing {@code i}. * @since 1.5 */ public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
上面的代码是说,进行自动拆装箱的时候,是有一个范围的,一旦超出这个范围,那么指向的就不是同一个对象,而是返回一个新创建的对象了,这个范围在Integer类中的一个内部私有类IntegerCache可以体现出来,源码如下:
private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }
从这里我们可以看出,范围值为[-128,127]之间。
注意,Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
Double、Float的valueOf方法的实现是类似的。
总结:这些进行自动拆装箱的基本类型的范围如下:
1. boolean类型的值
2.所有的byte的值
3.在-128~127的short类型的值
4.在-128~127的int类型的值
5.在 u0000~ u00ff 之间的char类型的值
而其中double和float又有所不同,我们就以double为例子,贴出代码讨论:
package com.ygh.CZX; /** * 关于java的拆装箱范围剖析 * * @author 夜孤寒 * @version 1.1.1 */ public class Test { /** * Double */ public static void first() { Double i1 = 100.0; Double i2 = 100.0; Double i3 = 200.0; Double i4 = 200.0; System.out.println(i1 == i2);//false System.out.println(i3 == i4);//false } /** * 测试方法 */ public static void main(String[] args) { first(); } }
注意为什么上面的代码的输出结果都是false呢?同样的我们依旧以Double类中的valueOf方法来讨论,贴出源码就一目了然了:
/** * Returns a {@code Double} instance representing the specified * {@code double} value. * If a new {@code Double} instance is not required, this method * should generally be used in preference to the constructor * {@link #Double(double)}, as this method is likely to yield * significantly better space and time performance by caching * frequently requested values. * * @param d a double value. * @return a {@code Double} instance representing {@code d}. * @since 1.5 */ public static Double valueOf(double d) { return new Double(d); }
也就是说不管你的double是什么范围的值,他都是给你返回一个新的对象。float同double,就不过多赘述了。
以上就是笔者对于拆装箱的一些整理,如果读者有不同的看法可以在评论区提出,笔者再进行修改!
java中的自动拆装箱
一:是什么 java的自动拆装箱,是从jdk1.5之后被引入的,java中的类型分为基本类型和引用类型,而自动拆装箱,可以让基本类型和对应的包装类,无缝转换。先拿最基本的来看。publicclassUntoBoxing{publicstaticvoidmain(String[]args... 查看详情
java自动拆装箱(autoboxingandunboxing)学习
在学习并发的过程中,用“Booleanbool=true”的自动装箱方式初始化了两个对象锁去锁两块代码,结果运行的时候出现了竞争等待,调试了一下发现两个锁变量指向的是同一个对象,由此可见我对自动拆装箱的机制想的太简单了,... 查看详情
一文读懂什么是java中的自动拆装箱
基本数据类型基本类型,或者叫做内置类型,是Java中不同于类(Class)的特殊类型。它们是我们编程中使用最频繁的类型。Java是一种强类型语言,第一次申明变量必须说明数据类型,第一次变量赋值称为变量的初始化。Java基本类... 查看详情
java连载78-深入自动拆装箱date类和simpledateformat格式化
一、深入自动拆装箱1.直接举例:publicclassD78_AutomaticUnpackingAndPacking{publicstaticvoidmain(String[]args){Integeri1=newInteger(10);Integeri2=newInteger(10);//这里不会自动进行拆箱System.out.println(i1==i2);//false//比较两个Int 查看详情
it十八掌作业_java基础第九天_多线程自动拆装箱
...性能是否一致?4.完成8中基本数据类包装类的练习,完成自动拆装箱操作。--------------------- 查看详情
it十八掌作业_java基础第九天_多线程自动拆装箱
1.蜜蜂和熊的生产消费关系,熊在蜂蜜满10斤吃掉。蜜蜂一次生产一斤蜂蜜,且蜜蜂生成一斤蜂蜜花费的时间是10s。 十只蜜蜂和两只熊。 classBeeextendsThread{ privateintbag; privatestaticfinalintBAG_MAX=20; privatestaticfinalintONCE=5; priv... 查看详情
比较中的自动拆装箱
...本型封装型进行“==”运算符的比较,基本型封装型将会自动拆箱变为基本型后再进行比较,因此Integer(0)会自动拆箱为int类型再进行比较,显然返回true;2、两个Integer类型进行“==”比较,如果其值在-128至127,那么返回true,否... 查看详情
什么是java中的自动拆装箱(代码片段)
个人博客请访问 http://www.x0100.top 本文主要介绍Java中的自动拆箱与自动装箱的有关知识。 1、基本数据类型 基本类型,或者叫做内置类型,是Java中不同于类(Class)的特殊类型。它们是我们编程中使用最频繁的类型。Java... 查看详情
自动拆装箱,string和基本数据类型的相互转换
1packagecom.pang.demo1;23publicclassDemo01{4publicstaticvoidmain(String[]args){5inti=1;6//转为包装类,自动装箱7Integera=i;8//转为基本类,自动拆箱9intvalue=a.intValue();10//基本数据类型,转化为string11Strings=i+"";12//string转化为基本数据 查看详情
可见参数和增强for以及自动拆装箱
可变参数:定义方法的时候不知道该定义多少个参数格式: 修饰符返回值类型方法名(数据类型…变量名) 注意: 这里的变量其实是一个数组如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最... 查看详情
java支持的数据类型有哪些?什么时候自动装拆箱?
...中的8种基本数据类型:booleanbytecharshortintfloatdoublelong 自动拆装箱的问题引入: 由于在一开始学习java的时候,”万物皆对象“这种面向对象的看问题方式,时刻围绕在脑海中。因为静态的变量和基本数据类型不属于对象... 查看详情
12.时间日期,字符串,内部类,拆装箱
...用4.区别:StringBuffer是线程安全,StringBuild非线程安全二.自动拆装箱1.基本类型转换为封装类型为装箱过程,反之则是拆箱过程2.八种基本数据类型对应的封装类型 Byteb;//byte Shorts;//short Integeri;//int Longl;//long Floatf;//float Doubled;/... 查看详情
类型转换及包装类拆装箱(代码片段)
1.基本类型2.基本类型之间的类型转换 (1)自动类型转换 (2)强制类型转换 (3)运算时类型提升 (4)类型转换中的符号扩展及“多重转型”3.基本类型到对应包装类 (1)包装类 (2)自动装箱与... 查看详情
基本类型包装拆装箱(代码片段)
基本类型包装就是转换用8个类型就是8个方法 除了int(Integer)和char(Character)之外,其他6个都是字符串转成基本类型得出结论想转成什么类型就用parase转成什么类型基本数据类型转字符串3种publicstaticvoidmain(String[]args)//字符... 查看详情
拆箱装箱版本区别(代码片段)
装箱:值类型=>>引用类型(jdk1.5以上版本,拥有自动装箱及自动拆箱功能)//引用类型可以newinti=10;Objecto=i;System.out.println(o);拆箱:引用类型=>>值类型Objectj=10;inta=(int)j;System.out.println(a);装箱:值类型=>>引用类型(jdk1.5... 查看详情
Java中的快速自动装箱/自动拆箱问题
】Java中的快速自动装箱/自动拆箱问题【英文标题】:Quickautoboxing/auto-unboxingquestioninJava【发布时间】:2018-10-1421:42:04【问题描述】:我刚刚了解了Java中自动装箱的概念,我有几个简单的问题可以帮助我澄清我的理解。据我了解... 查看详情
java基础自动装箱和拆箱面试题
JDK1.5(以后的版本)的新特性自动装箱和拆箱1.自动装箱:把基本类型转换为包装类类型 inta=10; Integeri=newInteger(a); Integervalue=10; 为什么基本类型就能直接转化为Integer,Integer不应该是new出来的吗 内部会自动的newInteger(10)自动装箱 2.... 查看详情
java字符串转成数字
...转换中起到重要的作用。基本数据类型和包装类之间可以自动拆装箱,因此在互相转换的时候不需要强制类型转换。我们将字符串String转换为数值int时,需要用到Integer.parseInt()方法,字符串左边的0无论有多少个都会去掉。将字... 查看详情