精华内容
下载资源
问答
  • Integer包装类的讲解自动装箱池 2.1 包装类的由来 在某些特殊场合(集合)中要求所有的数据必须都是对象,而对...
                                                                                                                                                 Integer包装类的讲解自动装箱池
    

    2.1 包装类的由来
    在某些特殊场合(集合)中要求所有的数据必须都是对象,而对于基本数据类型的变量来说并不满足该要求,此时就需要将这些变量进行对象化处理,那么借助包装类。

    2.2 Integer类(重点理解)
    (1)基本概念
    java.lang.Integer类是int类型的包装类,由final关键字修饰表示不能被继承。
    (2)装箱和拆箱的概念
    将int类型转换为Integer类型的过程叫做 装箱。
    从Integer类型转换为int类型的过程叫做 拆箱。
    从jdk1.5开始支持自动装箱和自动拆箱的机制。

    (3)自动装箱池(原理、尽量理解)
    为了提高自动装箱的效率,Integer类的内部提供了一个自动装箱池,将-128到127之间的整数装箱完毕并放入池中,当程序中出现该范围的数据时则直接从池中获取并使用。

    Integer a = 100, b = 100, c = 666, d = 666;
    Integer e=-128,f=-128,g=-127,h=-127,l=127,j=127,z=128,x=128;
    System.out.println(a == b);// true
    System.out.println(c == d);// false
    System.out.println(e == f);//true
    System.out.println(g == h);//true
    System.out.println(l == j);//true
    System.out.println(z == x);//false

    展开全文
  • 自动装箱池 在Integer类的内部提供了自动装箱池技术,将-128到127之间的整数已经装箱完毕,当程序中使用该范围之间的整数时,无需装箱直接取用自动装箱池中的对象即可,从而提高效率。 预测以下代码的运行结果 ...

    自动装箱池

    在Integer类的内部提供了自动装箱池技术,将-128到127之间的整数已经装箱完毕,当程序中使用该范围之间的整数时,无需装箱直接取用自动装箱池中的对象即可,从而提高效率。

    预测以下代码的运行结果

    public class IntegerTest {
        public static void main(String[] args) {
            Integer i1=128;//自动生成Integer对象
            Integer i2=128;
            Integer i3=new Integer(128);//新建对象
            Integer i4=new Integer(128);
            System.out.println(i1==i2);//比较地址
            System.out.println(i1.equals(i2));//比较内容
            System.out.println(i3==i4);//比较地址
            System.out.println(i3.equals(i4));//比较值 
        }
    }
    

    结果为
    在这里插入图片描述

    当将128改为127时

    public class IntegerTest {
        public static void main(String[] args) {
            Integer i1=127;//自动生成Integer对象
            Integer i2=127;
            Integer i3=new Integer(127);//新建对象
            Integer i4=new Integer(127);
            System.out.println(i1==i2);//比较地址 true
            System.out.println(i1.equals(i2));//比较内容 true
            System.out.println(i3==i4);//比较地址 false
            System.out.println(i3.equals(i4));//比较值 true
        }
    }
    

    结果如下:
    在这里插入图片描述
    当执行Integer i1=127时,将装箱池内值为127的对象的地址赋给了i1,执行Integer i2=127时,也指向了同一个对象,导致对i1、i2比较时,由地址相同导致结果为true。

    展开全文
  • 这种自动装箱的操作时,编译器会优先去常量里面找有没有包含i的常量,如果有,就直接把这个常量的引用给integer1,由于127在常量范围内,所以最终的结果是integer1等于integer2的引用。 后面把i的值改为128的...

    Java架构师交流群:793825326

    java版本:jdk1.8

    IDE:idea 18

    int是值类型,Integer是引用类型,Integer是int的包装类。不管怎么实例化Integer都是引用类型。参考如下代码:

    int i=127;
    
    Integer integer1=new Integer(i);
    Integer integer2=new Integer(i);
    System.out.println(integer1==integer2);
    System.out.println(integer1.equals(integer2));
    
    integer1=i;
    integer2=i;
    System.out.println(integer1==integer2);
    System.out.println(integer1.equals(integer2));
    
    i=128;
    integer1=i;
    integer2=i;
    System.out.println(integer1==integer2);
    System.out.println(integer1.equals(integer2));
    
    int a=integer1;
    int b=integer2;
    System.out.println(a==b);

    这段代码的运行结果如下:

    这里面首先integer1和integer2都是通过new的方式实例化的。在java里面,new就代表开辟一块内存空间。所以只要是new出来,不管equals是否相等,==的结果一定是false,因为它们是指向不同的引用(Integer的==操作表示比较引用,equals表示比较数值)。所以第一段代码的结果分别是false和true。

    integer1=i; integer2=i;这两句代码涉及到了自动装箱操作,所谓装箱是指将值类型转为引用类型,Integer integer1=new Integer(i);这个操作属于手动装箱,而java提供了自动装箱功能。integer1=i;这个操作java在运行的时候等价于Integer integer1=new Integer(i);但实际上有些区别,因为通过比较引用你会发现其结果是返回true。也就是引用相等。前面我们说过,只要new,引用肯定不会相等的。那为何这里会相等呢,原因是java里面有个数值常量池,这个常量池里面存放了-128到127之间的数值常量。当出现integer1=i;这种自动装箱的操作时,编译器会优先去常量池里面找有没有包含i的常量,如果有,就直接把这个常量的引用给integer1,由于127在常量池范围内,所以最终的结果是integer1等于integer2的引用。

    后面把i的值改为128的操作i=128;会导致自动装箱的时候,从常量池找不到,那么编译器就会new一个新的空间出来,所以integer1不等于integer2的引用。

    int a=integer1; int b=integer2; System.out.println(a==b);这部分代码是自动拆箱的操作,所谓拆箱,就是将引用类型转为值类型,这段代码你也可以这么写:

    int a=integer1.intValue();
    int b=integer2.intValue();
    System.out.println(a==b);

    这样的话就是手动拆箱了。

    这里为什么结果是true呢,是因为针对int这种非包装的基本类型,==被重写了,其作用相当于equals。

    现在我们看一下另外七种基本类型有没有这个特性:

    System.out.println("double:");
    double d=0.1d;
    Double double1=d;
    Double double2=d;
    System.out.println("是否有常量池:"+(double1==double2));
    System.out.println(double1.equals(double2)+"\r\n");
    
    System.out.println("float:");
    float f=0.1f;
    Float float1=f;
    Float float2=f;
    System.out.println("是否有常量池:"+(float1==float2));
    System.out.println(float1.equals(float2)+"\r\n");
    
    System.out.println("char:");
    char c='z';
    Character character1=c;
    Character character2=c;
    System.out.println("是否有常量池:"+(character1==character2));
    System.out.println(character1.equals(character2));
    
    character1=new Character(c);
    character2=new Character(c);
    System.out.println(character1==character2);
    System.out.println(character1.equals(character2)+"\r\n");
    
    System.out.println("byte:");
    byte b=127;
    Byte byte1=b;
    Byte byte2=b;
    System.out.println("是否有常量池:"+(byte1==byte2));
    System.out.println(byte1.equals(byte2));
    
    byte1=new Byte(b);
    byte2=new Byte(b);
    System.out.println(byte1==byte2);
    System.out.println(byte1.equals(byte2)+"\r\n");
    
    System.out.println("boolean:");
    Boolean boolean1=false;
    Boolean boolean2=false;
    System.out.println("是否有常量池:"+(boolean1==boolean2));
    System.out.println(boolean1.equals(boolean2));
    
    boolean1=new Boolean(false);
    boolean2=new Boolean(false);
    System.out.println(boolean1==boolean2);
    System.out.println(boolean1.equals(boolean2)+"\r\n");
    
    System.out.println("long:");
    long l=127;
    Long long1=l;
    Long long2=l;
    System.out.println("是否有常量池:"+(long1==long2));
    System.out.println(long1.equals(long2));
    
    long1=new Long(l);
    long2=new Long(l);
    System.out.println(long1==long2);
    System.out.println(long1.equals(long2)+"\r\n");
    
    System.out.println("short:");
    short s=127;
    Short short1=s;
    Short short2=s;
    System.out.println("是否有常量池:"+(short1==short2));
    System.out.println(short1.equals(short2));
    
    short1=new Short(s);
    short2=new Short(s);
    System.out.println(short1==short2);
    System.out.println(short1.equals(short2)+"\r\n");

    这段代码的执行结果如下:

    double:
    是否有常量池:false
    true

    float:
    是否有常量池:false
    true

    char:
    是否有常量池:true
    true
    false
    true

    byte:
    是否有常量池:true
    true
    false
    true

    boolean:
    是否有常量池:true
    true
    false
    true

    long:
    是否有常量池:true
    true
    false
    true

    short:
    是否有常量池:true
    true
    false
    true

    我们可以看到有常量池的是

    char:它的常量池范围是多少,我目前还搞不清,你可以尝试一下输入不同的char,看看输出结果。

    byte:它的常量池范围就是一个字节的大小,-128到127。

    boolean:它的常量池范围就两个false和true。

    long:同int。

    short:同int。

    short:同int。

     

    另外单独说一下string,string没有常量池,但是string在值相同的情况,只开辟一块内存空间:

    String string1="abcsfsdfsdfsdfsdfsdfsdgsgfdsgdsfsdghgfjghjfdgsdfs";
    String string2="abcsfsdfsdfsdfsdfsdfsdgsgfdsgdsfsdghgfjghjfdgsdfs";
    System.out.println(string1==string2);
    System.out.println(string1.equals(string2));
    
    string1=new String("abcsfsdfsdfsdfsdfsdfsdgsgfdsgdsfsdghgfjghjfdgsdfs");
    string2=new String("abcsfsdfsdfsdfsdfsdfsdgsgfdsgdsfsdghgfjghjfdgsdfs");
    System.out.println(string1==string2);
    System.out.println(string1.equals(string2)+"\r\n");

    这段代码的执行结果如下:

    true
    true
    false
    true

    这里面之所以第一次string1==string2为true,并不是常量池导致的结果,而是因为当String string2="abcsfsdfsdfsdfsdfsdfsdgsgfdsgdsfsdghgfjghjfdgsdfs";执行这句的时候,会检查内存区是否已经包含了值等于"abcsfsdfsdfsdfsdfsdfsdgsgfdsgdsfsdghgfjghjfdgsdfs"的string,如果有,则直接把地址给string2,如果没有,则开辟一个新的空间。

    同样的具备这个特性还包括八种基本数据类型。这里我们总结一下,只要代码中出现常量,什么意思呢,就是类似于"abc"、2、0.2这种东西,系统就会主动去常量池检查是否已经存在,如果不存在就创建一个常量,如果存在就直接把引用拿出来用。

    看下面的代码:

    String str="abc";
    System.out.println(str.intern()==str);

    执行结果为:true

    intern()的作用是去常量池检查是否存在值和str一样的常量,如果存在,就返回它的引用,如果不存在就创建一个,再返回它的引用。这里面因为代码中出现了"abc",会导致常量池多出来值等于"abc"的常量,这样通过str.intern()获取的引用自然和str的引用一样,因为它们都是指向常量池中的"abc"的引用。

    看下面的代码:

    String str=new String("abc");
    System.out.println(str.intern()==str);

    它的执行结果为false。

    由于代码中出现了"abc",所以虚拟机会去常量池里面检查是否存在"abc"这个常量,如果不存在则新建一个。同时还要新开辟一个存在str的内存空间,并把引用给str。这样其实产生了两个引用,常量池中的"abc"的引用和str的引用,str.intern()得到的是常量池中的"abc"的引用,str得到是因为new而新开的内存引用,那么自然str.intern()==str就会false了。

    关于这部分的详细信息可以看下这篇博客:https://blog.csdn.net/seu_calvin/article/details/52291082

    前面一种常量池,叫静态常量池,后面一种常量池,叫动态常量池。很明显,系统里面一开始肯定是没有"abcsfsdfsdfsdfsdfsdfsdgsgfdsgdsfsdghgfjghjfdgsdfs"这个常量的,但是随着系统的运行,这个常量出现,先去动态常量池检查是否已经存在,如果存在,则使用已有的,如果不存在,则在动态常量池增加一个常量

    展开全文
  • 一直以为Integer的自动装箱池的大小是-128~127,今天看了jdk1.6的源代码,发现其实并不一定的。 大家都知道java有8种基本类型,它们都有自己的包装类。而Byte,Character,Short,Integer,Long都有一个自动装箱池,我...

     

    一直以为Integer的自动装箱池的大小是-128~127,今天看了jdk1.6的源代码,发现其实并不一定的。

    大家都知道java有8种基本类型,它们都有自己的包装类。而Byte,Character,Short,Integer,Long都有一个自动装箱池,我一开始以为除了Character的自动装箱池的大小为0~127以外,其他都是-128~127。但是我在看jdk源代码的时候发现Integer的自动装箱池的实现跟其他几个包装类并不一样,我们先来看看Integer类好Short两个包装类的实现。

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

    Short和其他包装类(Character除外,不过原理一样,只是范围不一样)的自动装箱池的实现:

    private static class ShortCache {
        private ShortCache(){}
    
        static final Short cache[] = new Short[-(-128) + 127 + 1];
    
        static {
            for(int i = 0; i < cache.length; i++)
            cache[i] = new Short((short)(i - 128));
        }
        }

    经过比较我们发现,Integer的自动装箱池的最大值并不是一直是127的,当integerCacheHighPropValue不为空的时候,最大值是由integerCacheHighPropValue决定的。我们来看看integerCacheHighPropValue的是在哪儿被赋值的:

    private static String integerCacheHighPropValue;
    
        static void getAndRemoveCacheProperties() {
            if (!sun.misc.VM.isBooted()) {
                Properties props = System.getProperties();
                integerCacheHighPropValue =
                    (String)props.remove("java.lang.Integer.IntegerCache.high");
                if (integerCacheHighPropValue != null)
                    System.setProperties(props);  // remove from system props
            }
        }

    这段代码告诉我们,integerCacheHighPropValue是通过读取系统配置获得的,也就是说Integer的自动装箱池的大小是可以配置的。我们来看看

    getAndRemoveCacheProperties方法的注释就一目了然了。

    我们可以在虚拟机参数里面配置Integer的自动装箱池的大小。我们来验证一下。

    默认配置时,

     

     结果:

    修改虚拟机参数:

    结果:

    我们修改Integer的自动装箱池的大小为256。所以第二个输出的结果为true。由于第四个输出仍为false,所以我们还可以推断:修改虚拟机的AutoBoxCacheMax的大小只会影响Integer,而不会影响其他包装类。为什么其他包装类不跟Integer一样设计成可配置的呢?这就不得而知了。

     

     

     

    转载于:https://www.cnblogs.com/itnote/archive/2012/07/15/javaAutoBox.html

    展开全文
  • 自动装箱与拆箱     基本类型可以使用运算符直接进行计算,但是引用类型不可以,而基本类型包装类作为引用类型的一种却可以计算,这就是因为java中自动为我们做好了Integer转换成int类型,这就是自动拆箱。   ...
  • 自动装箱和自动拆箱实现原理!

    千次阅读 2019-03-06 15:58:41
    什么是自动装箱和拆箱 自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。因为这里的装箱和拆箱是...
  • Java自动装箱和拆箱的实现原理

    千次阅读 2019-10-02 10:02:31
    一、装箱和拆箱 原始类型转换为对象类型就是装箱,反之就是拆箱。 原始类型byte,short,char,int,long,float,double,...自动装箱时编译器调用valueOf将原始类型值转换成对象,同时自动拆箱时,编译器通过调用类似intV...
  • 什么是自动装箱和自动拆箱? 自动装箱就是Java自动将原始值类型转变为对应的对象,如int 自动转变为Integer的过程。 自动拆箱则反之。 Java是怎么实现自动装箱和拆箱的? 测试代码如下: public class AutoPacking {...
  • java 自动装箱与拆箱 这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的(在这种情况...
  • 什么是自动装箱,自动拆箱 自动装箱就是自动将基本数据类型转换为包装器类型; 自动拆箱就是自动将包装器类型转换为基本数据类型。 基本数据类型 int、short、long、float、double、byte、char、boolean。 包装器...
  • Java进阶之自动拆箱与自动装箱

    千次阅读 多人点赞 2016-06-06 18:04:26
    自动装箱:把基本类型用它们对应的包装类包装起来,使它们具有对象的特质,可以调用所对应的包装类所定义的方法,比如toString()等。 自动拆箱:跟自动装箱的方向相反,将Integer及Double这样的包装类的对象重新...
  • Java自动装箱与拆箱

    2018-04-13 00:49:52
    1、自动装箱Integer iObj = 3;//自动装箱2、自动拆箱System.out.println(iObj + 12); //自动拆箱3、演示代码package cn.sunft.day01; /** * @author sunft * */ public class AutoBox { /** * @param args ...
  • 自动装箱拆箱主要作用于基本数据类型于封装类中 比如: 1. Integer num=new Integer(10); 原始创建引用对象情况 现自动装箱: Integer i = 10 是不是变简单啦 2. 自动拆箱 int num1 = num 将引用数据类型对象转为...
  • Java中自动装箱、拆箱概念以及8种基本类型的包装类和常量 自动装箱、拆箱  装箱:将基本类型用他们对应的引用类型包装起来 Integer num = 88;//自动装箱,88为int类型,自动装箱成Integer类型  拆箱:将...
  • JAVA自动装箱

    2018-09-29 12:11:55
    //string 也适合装箱 public class AutoBoxingUnBoxingTest { public void test() { //i1 i2 不同对象 Integer i1 = new Integer(1000000); Integer i2 = new Integer(1000000); /...
  • 自动拆箱与自动装箱

    2018-10-11 16:40:24
    从源码中我们可以看到,下界是写死的,就是-128,但是上界却是由参数integerCacheHighPropValue解码得来的,这就表明,其实我们可以通过改变integerCacheHighPropValue值的大小来自定义自动装箱池的大小,当然,一般...
  • 自动拆箱和自动装箱的面试陷阱题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容...
  • 自动装箱和拆箱

    2017-04-09 16:49:48
    自动装箱和拆箱是什么在Java中,数据类型可以分为两大类:Primitive Type(原始类型)和Reference Type(引用类型)。基本类型的数值不是对象,不能调用对象的toString()、hashCode()、getClass()、equals()等方法。...
  • 1.基本类型对应的包装类 byte->Byte; short->Short; int->Integer; long->Long; double->Double; float->Float; char->Charecter;...2. 自动拆箱与自动装箱 自动装...
  • 因为整型的包装类存在常量,一次性把从-128到127之间的所有数都初始化了.当你使用这些数的时候不是创建新对象而是直接从这个常量里面取值.所以当你赋值100的时候是取的常量里的100,因此两个对象 内存地址 一样....
  • 1.自动装箱与拆箱的定义装箱就是自动将基本数据类型转换为包装器类型;拆箱就是 自动将包装器类型转换为基本数据类型。Java中的数据类型分为两类:一类是基本数据类型,另一类是引用数据类型。如下图:由上可知Java...
  • 上期我们讲过自动拆箱自动装箱是JDK1.5之后的新特性 下面我们讲讲关于这里的一个“128陷阱” public static void main(String[] args) { Integer i=10; Integer j=10; System.out.println("i和j比较"); System....
  • ② -128到127是byte的取值范围,在此范围内,自动装箱不创建新对象,而是从常量中直接获取。 ③ 如果超过了byte取值范围就会再新创建对象 public class Demo5_Integer { public static void main(String[] args) { ...
  • 自动拆箱与自动装箱六. 自动装箱/自动拆箱原理七. 分析自动拆装箱使用场景八. 自动拆装箱与缓存九.使用包装类弊端 一. 八大基本数据类型 基本类型,或者叫做内置类型,是Java中不同于类(Class)的特殊类型。它们是...
  • 自动拆箱(unboxing)&自动装箱(boxing) @author 李东秀|| qq:1028659927 本文主要为自己理解所做的学习笔记,如有不对的地方, 望各位看官不吝指出,代码运行环境:Ubuntu 14.04,jdk1.7版本  在jdk 1.5...
  • 字符串相等5.Java基本数据类型基本数据类型与封装好的类的区别:Integer与int的区别:6.Java的自动拆箱和装箱7.Integer和int的比较 1.String类,StringBuffer类以及StringBuilder类 首先String类是不可变类,即一旦...
  • 基本类型变为包装类型就是自动装箱,反之就是自动拆箱,下面是具体场景。 Integer i = 100; //自动装箱,类似于Integer i = Integer.valueOf(100); int j = i; //自动拆箱,类似于int j = i.intValue();  
  • Java自动装箱和拆箱

    2017-12-13 20:40:10
    title:Java自动装箱和拆箱date:2017年10月27日15:04:35categories: Java基础前言相信大家在写代码的时候,都写过至少看到过这样的代码:Integer i=100;那你写的时候,有没有想过为什么可以直接这样写呢,Integer...
  • java基础--06(自动装箱拆箱)

    千次阅读 多人点赞 2019-02-11 16:40:27
    1.自动装箱,自动拆箱 1.自动装箱,自动拆箱 装箱就是自动将基本数据类型转换为包装器类型;拆箱就是 自动将包装器类型转换为基本数据类型。 java的数据类型: 自动装箱: 最主要的就是Integer b=a;这...
  • JAVA 自动装箱拆箱

    2018-03-28 15:44:31
    而基本类型包装类作为引用类型的一种却可以计算,原因在于,Java”偷偷地”自动地进行了对象向基本数据类型的转换。 相对应的,引用数据类型变量的值必须是new出来的内存空间地址值,而我们可以将一个基本类型的值...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,768
精华内容 7,107
关键字:

自动装箱池