精华内容
下载资源
问答
  • 2021-02-12 09:25:59

    自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动地转换成对应的对象。自动装箱与拆箱的机制可以让我们在Java的变量赋值或者是方法调用等情况下使用原始类型或者对象类型更加简单直接。

    如果你在Java1.5下进行过编程的话,你一定不会陌生这一点,你不能直接地向集合(Collections)中放入原始类型值,因为集合只接收对象。通常这种情况下你的做法是,将这些原始类型的值转换成对象,然后将这些转换的对象放入集合中。使用Integer,Double,Boolean等这些类我们可以将原始类型值转换成对应的对象,但是从某些程度可能使得代码不是那么简洁精炼。为了让代码简练,Java 1.5引入了具有在原始类型和对象类型自动转换的装箱和拆箱机制。但是自动装箱和拆箱并非完美,在使用时需要有一些注意事项,如果没有搞明白自动装箱和拆箱,可能会引起难以察觉的bug。

    本文将介绍,什么是自动装箱和拆箱,自动装箱和拆箱发生在什么时候,以及要注意的事项。

    什么是自动装箱和拆箱

    自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。因为这里的装箱和拆箱是自动进行的非人为转换,所以就称作为自动装箱和拆箱。原始类型byte,short,char,int,long,float,double和boolean对应的封装类为Byte,Short,Character,Integer,Long,Float,Double,Boolean。

    自动装箱拆箱要点

    自动装箱时编译器调用valueOf将原始类型值转换成对象,同时自动拆箱时,编译器通过调用类似intValue(),doubleValue()这类的方法将对象转换成原始类型值。

    自动装箱是将boolean值转换成Boolean对象,byte值转换成Byte对象,char转换成Character对象,float值转换成Float对象,int转换成Integer,long转换成Long,short转换成Short,自动拆箱则是相反的操作。

    何时发生自动装箱和拆箱

    自动装箱和拆箱在Java中很常见,比如我们有一个方法,接受一个对象类型的参数,如果我们传递一个原始类型值,那么Java会自动讲这个原始类型值转换成与之对应的对象。最经典的一个场景就是当我们向ArrayList这样的容器中增加原始类型数据时或者是创建一个参数化的类,比如下面的ThreadLocal。

    举例说明

    上面的部分我们介绍了自动装箱和拆箱以及它们何时发生,我们知道了自动装箱主要发生在两种情况,一种是赋值时,另一种是在方法调用的时候。为了更好地理解这两种情况,我们举例进行说明。

    赋值时

    这是最常见的一种情况,在Java 1.5以前我们需要手动地进行转换才行,而现在所有的转换都是由编译器来完成。

    方法调用时

    这是另一个常用的情况,当我们在方法调用时,我们可以传入原始数据值或者对象,同样编译器会帮我们进行转换。

    show方法接受Integer对象作为参数,当调用show(3)时,会将int值转换成对应的Integer对象,这就是所谓的自动装箱,show方法返回Integer对象,而int result = show(3);中result为int类型,所以这时候发生自动拆箱操作,将show方法的返回的Integer对象转换成int值。

    自动装箱的弊端

    自动装箱有一个问题,那就是在一个循环中进行自动装箱操作的情况,如下面的例子就会创建多余的对象,影响程序的性能。

    上面的代码sum+=i可以看成sum = sum + i,但是+这个操作符不适用于Integer对象,首先sum进行自动拆箱操作,进行数值相加操作,最后发生自动装箱操作转换成Integer对象。其内部变化如下

    由于我们这里声明的sum为Integer类型,在上面的循环中会创建将近4000个无用的Integer对象,在这样庞大的循环中,会降低程序的性能并且加重了垃圾回收的工作量。因此在我们编程时,需要注意到这一点,正确地声明变量类型,避免因为自动装箱引起的性能问题。

    重载与自动装箱

    当重载遇上自动装箱时,情况会比较有些复杂,可能会让人产生有些困惑。在1.5之前,value(int)和value(Integer)是完全不相同的方法,开发者不会因为传入是int还是Integer调用哪个方法困惑,但是由于自动装箱和拆箱的引入,处理重载方法时稍微有点复杂。一个典型的例子就是ArrayList的remove方法,它有remove(index)和remove(Object)两种重载,我们可能会有一点小小的困惑,其实这种困惑是可以验证并解开的,通过下面的例子我们可以看到,当出现这种情况时,不会发生自动装箱操作。

    要注意的事项

    自动装箱和拆箱可以使代码变得简洁,但是其也存在一些问题和极端情况下的问题,以下几点需要我们加强注意。

    对象相等比较

    这是一个比较容易出错的地方,”==“可以用于原始值进行比较,也可以用于对象进行比较,当用于对象与对象之间比较时,比较的不是对象代表的值,而是检查两个对象是否是同一对象,这个比较过程中没有自动装箱发生。进行对象值比较不应该使用”==“,而应该使用对象对应的equals方法。看一个能说明问题的例子。

    值得注意的是第三个小例子,这是一种极端情况。obj1和obj2的初始化都发生了自动装箱操作。但是处于节省内存的考虑,JVM会缓存-128到127的Integer对象。因为obj1和obj2实际上是同一个对象。所以使用”==“比较返回true。

    容易混乱的对象和原始数据值

    另一个需要避免的问题就是混乱使用对象和原始数据值,一个具体的例子就是当我们在一个原始数据值与一个对象进行比较时,如果这个对象没有进行初始化或者为Null,在自动拆箱过程中obj.xxxValue,会抛出NullPointerException,如下面的代码

    缓存的对象

    这个问题就是我们上面提到的极端情况,在Java中,会对-128到127的Integer对象进行缓存,当创建新的Integer对象时,如果符合这个这个范围,并且已有存在的相同值的对象,则返回这个对象,否则创建新的Integer对象。

    在Java中另一个节省内存的例子就是字符串常量池,感兴趣的同学可以了解一下。

    生成无用对象增加GC压力

    因为自动装箱会隐式地创建对象,像前面提到的那样,如果在一个循环体中,会创建无用的中间对象,这样会增加GC压力,拉低程序的性能。所以在写循环时一定要注意代码,避免引入不必要的自动装箱操作。

    总的来说,自动装箱和拆箱着实为开发者带来了很大的方便,但是在使用时也是需要格外留意,避免引起出现文章提到的问题

    要理解装箱和拆箱的概念,就要理解Java数据类型

    装箱:把基本类型用它们相应的引用类型包装起来,使其具有对象的性质。int包装成Integer、float包装成Float

    拆箱:和装箱相反,将引用类型的对象简化成值类型的数据

    Integer a = 100;                  这是自动装箱  (编译器调用的是static Integer valueOf(int i))

    int     b = new Integer(100); 这是自动拆箱

    更多相关内容
  • 主要介绍了深入理解Java中的装箱和拆箱,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • java装箱和拆箱的区别

    2021-03-10 11:15:08
    装箱就是自动将基本数据类型转换为包装器类型(int–>Integer);调用方法:Integer的valueOf(int) 方法。 拆箱就是自动将包装器类型转换为基本数据类型(Integer–>int);调用方法:Integer的intValue方法。...
    • 装箱就是自动将基本数据类型转换为包装器类型(int–>Integer);调用方法:Integer的valueOf(int) 方法。
    • 拆箱就是自动将包装器类型转换为基本数据类型(Integer–>int);调用方法:Integer的intValue方法。

    自动装箱和拆箱发生在编译器

    Integer x = 2;     // 装箱 调用了 Integer.valueOf(2)
    int y = x;         // 拆箱 调用了 X.intValue()
    

    面试题01:以下代码会输出什么?

    public void Test01(){
            Integer i1 = 100;
            Integer i2 = 100;
    
            Integer i3 = 200;
            Integer i4 = 200;
    
            System.out.println(i1 == i2);
            System.out.println(i3 == i4);
    
        }
    

    结果:

    true
    false
    

    原因:看一下源码

    public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
    

    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() {}
        }
    

    代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。

    上面代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则分别指向不同的对象。

    面试题01:以下代码会输出什么?

     public void test02(){
            Double d1 = 100.0;
            Double d2 = 100.0;
    
            Double d3 = 100.0;
            Double d4 = 100.0;
    
            System.out.println(d1 == d2);
            System.out.println(d3 == d4);
        }
    

    结果:

    false
    false
    

    原因:在某个范围内的整型数值的个数是有限的,而浮点数却不是。

    基本类型对应的缓冲池如下:

    • boolean values true and false
    • all byte values
    • short values between128 and 127
    • int values between -128 and 127
    • char in the range \u0000 to \u007F

    面试题03 new Integer(123) 与 Integer.valueOf(123) 的区别在于:

    • new Integer(123) 每次都会新建一个对象;
    • Integer.valueOf(123) 会使用缓存池中的对象,多次调用会取得同一个对象的引用。
    展开全文
  • Java装箱和拆箱详解

    千次阅读 多人点赞 2018-07-12 17:47:10
    Java装箱和拆箱详解 题外话 今天早上在学习公司代码,然后准备学习下MVP框架,于是找了个简单的MVP框架例子,结果在框架中,发现了一个类叫SparseArray的类,秉持着一种遇到问题就深究下去的精神,我就转去看...

    Java装箱和拆箱详解


    题外话

    今天早上在学习公司代码,然后准备学习下MVP框架,于是找了个简单的MVP框架例子,结果在框架中,发现了一个类叫SparseArray的类,秉持着一种遇到问题就深究下去的精神,我就转去看SparseArray相关的知识,结果发现了一片新天地,顺带研究了一番Android里的几个集合类,主要是SparseArray和ArrayMap,然后我就想,Java里不是有了很多集合类了嘛,比如HashMap,TreeMap,ArrayList,LinkList等等,为啥Android还要再弄一个呢,何况Android本身就是基于Java的,于是我又屁颠屁颠去找相关资料,结果,又发现一个小岛(这个应该不是新大陆,额嘿嘿!),这个小岛就是Java装箱和拆箱,,为了弄清楚Android为啥还要专门弄个自己的集合类,于是就有了这篇文章,关于问题的答案就放在文章结语中吧!!

    目录

    • 小例子引发的思考
    • 源码欣赏及解析
    • 装箱拆箱的时机
    • 引发的细节问题
    • 小小结语

    正文

    小例子引发的思考

    	public static void main(String[] args) {
    		int i0=10;
    		int i1=10;
    		int i2=500;
    		int i3=500;
    		Integer i4=new Integer(10);
    		Integer i5=new Integer(10);
    		Integer i6=new Integer(500);
    		Integer i7=new Integer(500);
    		System.out.println("i0==i1?  "+(i0==i1));
    		System.out.println("i2==i3?  "+(i2==i3));
    		System.out.println("i4==i5?  "+(i4==i5));
    		System.out.println("i6==i7?  "+(i6==i7));
    	}
    

    这是一个很简单的例子,我们来看一下它的运行结果

    i0i1? true
    i2
    i3? true
    i4i5? false
    i6
    i7? false

    怎么样,和预想的是一样的吗,这里主要就是一个知识点,Java中,基本类型的比较的是值,而封装类型比较的是对象的地址,所以后面两个是false。
    好了,我们再把这个代码改一改

    	public static void main(String[] args) {
    		Integer i8 = 40;
    		Integer i9 = 40;
    		Integer i10 = 500;
    		Integer i11 = 500;
    		Double d0 = 40.0;
    		Double d1 = 40.0;
    		Double d2 = 500.0;
    		Double d3 = 500.0;
    		System.out.println("i8==i9?  " + (i8 == i9));
    		System.out.println("i10==i11?  " + (i10 == i11));
    		System.out.println("d0==d1?  " + (d0 == d1));
    		System.out.println("d2==d3?  " + (d2 == d3));
    	}
    

    让我们再来看看结果,是不是你预想中的样子呢

    i8i9? true
    i10
    i11? false
    d0d1? false
    d2
    d3? false

    嘿嘿,你现在可能就有点迷了,没关系,接着往下看

    	public static void main(String[] args) {
    		Integer i12 = new Integer(40);
    		Integer i13 = new Integer(40);
    		Integer integer0 = new Integer(0);
    		System.out.println("i12==i13?  " + (i12 == i13));
    		System.out.println("i12==i13+integer0?  " + (i12 == i13 + integer0));
    	}
    

    结果可能会是什么呢…

    i12i13? false
    i12
    i13+integer0? true

    怎么样,猜对了嘛,是不是一脸蒙加上&%¥#@*,没事,下面我们来找下原因,看看到底为啥答案回事这样的。

    源码欣赏及解析

    在欣赏美(cao)妙(dan)的Java源码前,我们首先需要知道的是,jdk源码偷偷在哪里给我们做了装箱和拆箱的工作,答案就是valueOf()和xxxValue()这两个方法,你会发现,不管是Integer还是Double还是Short等,都有着两个方法,其中在Integer中,xxxValue叫做intValue,其它的类似,好了,我们现在知道了装箱拆箱的源码在哪,我们再去源码一探究竟。
    首先是Integer的

        public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
    

    在Integer中,valueOf有三个重载方法,但是最终都会转到上面参数为int的方法,代码不多,我们简单看下,首先判断拿到的i是否在某个范围内,如果满足添加条件的话,则返回一个数组对应下标的值,我们暂且先不管这个数组是啥,然后如果不满足条件的话,则直接用i来new一个新的Integer对象。
    大致流程就是上面说的,接下来我们再定位到IntegerCache类里,这个是Integer类的一个内部类,我们看看里面是些啥

    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() {}
        }
    

    代码也不多,静下心来一行一行读,首先它声明了三个静态常量,一个low赋了初值-128,一个high没有赋值,默认为0(这里也很容易想到high就是127),一个Integer数组(取名为cache,多多少少都可以猜想到是用来干嘛的,~~~)。
    接下来,是一个静态代码块,保证只会加载一次,在这部分代码里面,首先做的就是为high赋值,因为声明的时候只给low赋值了,然后通过sun.misc.VM.getSavedProperty(“java.lang.Integer.IntegerCache.high”)获取一个值,这个值是干嘛的呢,这个其实是获取一个私有配置文件里的值,这个值可以去配置修改,在JVM初始化的时候,就会加载,得到这个值赋值给i后,再将i和127做比较,取最大的赋值给i,然后再将新得到的i值和Integer的最大值相比较,取较小者,然后赋值给h,最后再赋值给high。
    简单点说,就是high的值是取自于配置文件中的一个值,但是这个值可能很小,也可能很大,毕竟是一个文件,我想配置为多少就配置为多少,然后拿到这个值后会做个限定,如果它小于127,那么就取127,如果它大于MAX_VALUE,那么就取值MAX_VALUE+low-1。
    好,接着往下看,随后为数组cache开辟了地址空间,大小为high-low+1,然后再从0下标开始初始化对应的值从low开始(也就是-128)递增。至此结束。
    在开始接下来的讨论前,假定配置文件的值是默认的,也就是最终high取值127,那么这个cache数组到底起到了什么作用呢?结合上面的valueOf代码片段你会发现,如果给定的基本类型int值在-128到127之间的话,就会直接去cache数组里取,如果不在这个范围的话,那么就会创新的对象,到这里你也就明白了为啥用40和500这两个基本类型声明包装类型Integer时(装箱),不同的值居然结果不一样的原因。
    那么问题来了,这样做有啥好处呢?你想想这个问题,你平常使用的int类型是不是大都在-128到127之间,也就说这个范围是一个“热”范围,为了节约内存开销,在新声明的值在-128-127之间的Integer包装类型时,直接从预加载的缓存中去取,这个缓存机制上面就已经解释了,就是从一个cache数组中取,不在-128-127这个范围的才需要重新new对象,而new对象是需要内存的,如果没有这个缓存机制,那么只要是遇到需要装箱的情形,那么全部都要声明新的Integer对象,而且很多还是重复的,浪费了大量的内存,这当然不是我们想要看到的。(不禁感叹,jdk源码设计者真的是煞费苦心啊!)
    至此,弄清楚了装箱的原理,下面我们再去intValue方法看看,拆箱是怎么做的,源码如下

    	public int intValue() {
            return value;
        }
    

    嘿嘿,只有一行代码呢,真的简单,这个value值是一个内部变量,在声明Integer对象的时候用的,这里直接返回即可得到拆箱后的结果,不过你要是细心的话,你会发现还有类似的shotValue、longValue等方法,代表也可以直接拆箱成short等类型的。
    同理,明白了Integer的装箱原理之后,相信你也应该猜到了Byte或者Short或者Long的实现原理,我们就不一一去看了,一共八种基本类型,其中byte,short,char,int,long这五种基本类型的装箱实现原理都和int类似,虽然它们之间有一点点区别,但是大同小异,我们就不一一去看了,然后还剩下boolean和float和double,我们先看Boolean里的

        public static Boolean valueOf(boolean b) {
            return (b ? TRUE : FALSE);
        }
    

    嗯,看着挺清爽的,比Integer的简单多了,嘿嘿,这个,我就不多解释了吧。注释这里的TRUE是大写的哦,和小写的true不一样,算了还是啰嗦一下吧,不放心啊,这里的TRUE是一个对象,声明如下

    public static final Boolean TRUE = new Boolean(true);

    可以看到是一个静态常量对象,保证不会有重复的对象,不消耗内存。因为Boolean是一个比较奇葩的,毕竟只有两个值,所以也不用像Integer那样去弄个缓存机制。
    接下来就是Float和Double,将这两个放在一起是因为这两个是类似的,相比较于Integer,它们的区别就是,没有采用缓存机制,也就是没有设置“热”范围,仔细思考即可知道,这个要设置“热”范围的话,其实是不好处理的,因为精度问题可能还得不偿失,加上本身Float和Double在开发中相对用的比较少,所以没有设置缓存策略,我们还是象征性的看一下Double的valueOf方法意思一下吧

        public static Double valueOf(double d) {
            return new Double(d);
        }
    

    简单粗暴,不管你是哪个值,统统创建新的包装类型对象,Float一模一样。
    好了,到现在,再回过头去看看之前的测试用例,你就明白为啥同样是40的值,Integer就是true,而Double就是false,原因就是Integer的装箱采用了缓存策略,但是Double没有作处理。
    然后是最后一个测试用例的解释:为啥我在比较两个值相等的对象时,为false,但是我再后者加了一个值为0的对象时,再比较就是true了呢,真的是不明觉厉呀,于是,就又引出了一个问题,何时会发生装箱和拆箱呢?

    装箱拆箱的时机

    • 赋值
    • 包装类型计算

    其实这个时机是很多的,怎么解释呢,明白原理之后,其实你就知道只要是遇到需要将基本类型转换为包装类型时就需要装箱,将包装类型转换为基本类型时就需要拆箱。秉持着这个原则就不会有啥疑问了。
    这时,我们再看刚才测试用例的最后一个,比较的代码是i12 == i13 + integer0,首先看等号后面,两个Integer对象相加时,肯定是没法直接相加的,所以java编译器就会进行拆箱的过程,将其拆箱为基本类型int,然后得到相加后的和,这个和仍然是基本类型int,所以在和前者比较时,也没法比较,再将前者也拆箱为基本类型int(也就是int和Integer比较时,会将Integer拆箱),然后==号比较2个int的值,发现相等,于是结果为true。

    引发的细节问题

    看到这里,已经对装箱和拆箱有了比较全面的了解,但是我还有个疑问,这样装箱拆箱的,对于实际的开发者来说,有啥影响呢?好像我之前不知道这些东西也没有关系,仍然在做我的工作,知道不知道对我没啥影响,那我知道这个东西干嘛?
    嘿嘿,首先需要明白的一个问题就是,这样做肯定是有道理的。那么道理何在呢?看个例子

    	Integer sum = 0;
        //int sum = 0; 一样?
    	for (int i = 0; i < 100; i++) {
    		sum += i;
    	}
    

    用包装类声明的sum在循环迭代时,由于是包装类,无法直接与基本类型int类型的i相加,所以需要先拆箱,再加,再装箱,每次相加,都需要进行这个过程,那么时间效率和用int来声明相比,就不是一个档次的了,所以在开发中,要注意这些细节问题。

    小小结语

    好了,我们回到文章开篇的那个问题,也就是SparseArray、ArrayMap的诞生原因,平常我们在Java中使用的都是HashMap等来保存数据,但是有一个严重的问题就是HashMap里的key以及value都是泛型,那么就会不可避免的遇到装箱和拆箱的过程,而这个过程是很耗时的,所以为了规避装箱拆箱提高效率,于是诞生了SparseArray等集合类,但是SparceArray效率高也是有条件的,它适用于数据量比较小的场景,而在Android开发中,大部分场景都是数据量比较小的,在数据很大的情况下,当然还是hashmap效率较优,至于具体SparseArray是怎么实现的,这个我准备单独弄一篇文章,有兴趣的可以关注下。
    好了,至此文章也完结了,再说点题外话,不得不说,Java的设计是很优秀的,毕竟一个团队的心血,这不,今天就学到了一个看似普通的Integer类中的缓存设计思想,所以,小小结语:没事就看看源码,说不定你就发现了一个优秀的设计呢!!!

    展开全文
  • 装箱和拆箱是java中老生常谈的问题,下面小编通过本文给大家介绍java装箱和拆箱最基本的东西,感兴趣的朋友一起看下吧
  • java中的装箱和拆箱

    2022-02-20 16:03:21
    java中的装箱和拆箱 1. 什么是装箱和拆箱 Java中的数据类型项由8大基本数据类型引用数据类型,其中基本数据类型存储在栈中,而引用类型的数据则在栈中存储了一个地址,引用类型的数据则存储在堆中;(这里需要注意...

    java中的装箱和拆箱

    1. 什么是装箱和拆箱
    Java中的数据类型项由8大基本数据类型和引用数据类型,其中基本数据类型存储在栈中,而引用类型的数据则在栈中存储了一个地址,引用类型的数据则存储在堆中;(这里需要注意的是这里的堆和数据结构中的堆没有任何关系,我们可以把堆看作是一个池)

    而所谓装箱就是把基本数据类型存储在堆中,所以要把他变成引用类型;反过来所谓拆箱,就是把引用类型中的数据放到栈中,要把它变成基本数据类型。

    Java中给我们提供很多的包装类,可以参考帮助文档学习:
    java JdkAPI下载

    小案例:

    package com.iobox.dem01;
    
    public class Test {
        public static void main(String[] args) {
            //基本类型;
            int num1=18;
            //装箱,基本数据类型转换为引用数据类型。
            //使用Integer类创建对象
            System.out.println("装箱:");
            Integer integer1=new Integer(num1);
            Integer integer2=Integer.valueOf(num1);
            System.out.println(integer1);
            System.out.println(integer2);
    
            //类型转换,拆箱:引用类型转换为基本类型
            System.out.println("拆箱:");
            Integer integer4=new Integer(100);
            int num2=integer4.intValue();
            System.out.println(num2);
    
            //jdk1.5之后,自动提供装箱和拆箱
            int num3=120;
            //自动装箱
            Integer interger5=num3;
            System.out.println("自动装箱:"+interger5);
            System.out.println(interger5.getClass());
            //自动拆箱
            int num4=interger5;
            System.out.println("自动拆箱:"+num4);
        }
    }
    
    

    2. 基本数据类型和字符串之间的转换

    • 基本数据类型转化为string数据类型,可以使用 + 号;也可以使用Integer类中的toString()方法;
    • 字符串型转换为基本数据类型,使用Integer.parsXXX()
    • boolean字符串形式转成基本数据类型,即"true"—>true ,其中只要是 非"true"那就转化false;

    案例:

    package com.iobox.dem01;
    
    public class Test01 {
        public static void main(String[] args) {
            //1基本数据类型转换为string数据类型
            int num1=124;
            //1.1使用+号
            String s1=num1+"";
            System.out.println(s1);
            //1.2使用Integer类中的toString()方法
            String s2=Integer.toString(num1,16);//16表示16进制
            System.out.println(s2);
    
            //2.字符串转成基本数据类型
            String str="150";
            //使用Integer.parsXXX()
            int n1=Integer.parseInt(str);
            System.out.println(n1);
    
            //boolean字符串形式转成基本数据类型,"true"--->true  || 非"true"-->false
            String str2="true";
            boolean b1= Boolean.parseBoolean(str2);
            System.out.println(b1);
        }
    }
    
    
    展开全文
  • java中的装箱和拆箱详解
  • 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题。本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱拆箱相关的问题。以下是本文的目录...
  • Java装箱拆箱详解(附实例代码)本文是百分网小编搜索整理的主要介绍Java 装箱与拆箱详解及实例代码的相关资料,对java 的装箱及拆箱进行了基本概念详解及简单使用,供参考学习,希望对大家有所帮助!想了解更多相关...
  • java自动装箱拆箱

    2022-04-06 15:58:36
    包装类 ...包装类有8种,包装类位于 java.lang.文件下 基本类型 对应的包装类(位于java.lang包中) byte Byte short Short int Integer long Long float Float double Double cha
  • 装箱: 是通过调用包装器类的valueOf方法实现的。 例:int 装箱的时候会自动调用Integer的valueOf(int)方法 拆箱: 是通过调用包装器类的xxx.value方法实现的,xxx代表对应的基本数据类型。 例:Integer拆箱的...
  • 主要介绍了Java 装箱拆箱详解及实例代码的相关资料,这里对java装箱拆箱进行了基本概念详解及简单使用,需要的朋友可以参考下
  • 文章目录001、基本类型010、装箱011、拆箱100、用途 001、基本类型 在java中有八种基本数据类型对应每种基本类型又有八种包装类型: 基本类型:boolean, char, int, byte,short,long, float,double 包装器...
  • Java中的拆箱和装箱

    2021-04-17 08:42:19
    一般可以通过javap -c 命令可以反编译class文件获取拆箱和装箱是如何实现的。就比如Integer,在装箱的时候自动调用的Integer的valueOf(int)方法.而在拆箱的时候自动调用Integer的intValue方法,其他的类型也类似.因此....
  • 1、装箱拆箱装箱,将基本数据类型转为包装类型。拆箱,将包装类型转为基本数据类型。//Byte, Short, Integer, Long, Double, Float, Boolean, Character//自动装箱,将基本数据类型转为包装类型Integer i1 = 200;...
  • JAVA中的装箱拆箱

    2021-07-27 11:02:40
    1、定义:装箱是将值类型装换成引用类型的过程;拆箱就是将引用类型转换成值类型的过程; 装箱:用于在垃圾回收堆中储存值类型。装箱是值类型到Object类型或到此类型所实现的任何接口类型的隐式转换。 拆箱:从object...
  • Java中的装箱拆箱

    2020-12-28 15:02:01
    一.什么是装箱?什么是拆箱?  在前面的文章中提到,Java为每种基本数据类型都提供了对应的包装器...  而在从Java SE5开始就提供了自动装箱的特性,如果要生成一个数值为10的Integer对象,只需要这样就可以了: ..
  • Java 装箱和拆箱

    2022-06-11 00:11:10
    java呢是一门面向对象的语言,正所谓对象,是指引用数据类型的,但是后面会用到基本数据类型的次数越来越多,所以要想办法讲基本数据类型转换为引用数据类型。装箱:把基本数据类型的数据转换为包装类的对象,这个...
  • java中的装箱拆箱

    2021-03-09 22:57:35
    什么是自动装箱拆箱基本数据类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。一般我们要创建一个类的对象实例的时候,我们会这样:Class a = new Class(parameter);当我们创建一个Integer...
  • Java基础之拆箱和装箱

    千次阅读 2022-03-07 14:00:49
    Java基础之拆箱和装箱 一、什么是拆箱和装箱 1)什么是拆箱 • 拆箱就是自动将包装器类型转换为基本数据类型 • 拆箱调用Integer.intValue方法 2)什么是装箱装箱就是自动将基本数据类型转换为包装器类型 • ...
  • 装箱:把基本类型的数据,包装到包装类中白的少的硬的狼 扶狼的大波被楞插byte short int long float double boolean char构造方法:1.Integer(int value) 构造一个新分配的Integer对象,它表示指定的int值2.Integer...
  • Java中的装箱拆箱

    2021-03-14 11:08:03
    一) 装箱拆箱Java中有概念是一切皆对象,因为...为了同一“一切接对象“这个概念,Java提供了装箱和拆箱功能。也就是说Java为上面这八种数据类型提供了对应的Java类(包装类)实现。如下:intIntegershortShortlong...
  • JAVA面试题装箱拆箱

    2021-07-05 19:54:53
    装箱:将基本类型值装到对象中去,封装为引用类型 拆箱:将对象中的值取出来,赋值给基本类型 装箱: int m=200; Integer n=Integer.valueOf(m); 拆箱:int a=n.intValue(); 自动:直接赋值不需要调用方法 装箱:...
  • 基本数据(Primitive)类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的(在这种情况下包装成为装箱,解包装称为拆箱
  • java-拆箱和装箱

    2022-01-29 01:07:48
    Java 1.5 版本之前必须手动拆箱装箱,之后可以自动拆箱装箱. 也就是在进行基本数据类型对应的包装类转换时,系统将自动进行装箱拆箱操作. 不用在进行手工操作,为开发者提供了更多的方便。 pub
  • ​ (2)定义:拆箱和装箱使非人为的,自动装箱能在java中将基本类型转换为引用类型,比如int值转为Integer 对象,反之为拆箱。 ​ (3)拆箱和装箱的基本类型:byte、short、 int、long、float、 double、boolean、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 50,720
精华内容 20,288
关键字:

java的装箱和拆箱

java 订阅