精华内容
下载资源
问答
  • Java中自动拆装箱

    2017-11-04 13:05:56
    自动拆装箱

    什么是自动装箱拆箱

    基本数据类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。

    一般我们要创建一个类的对象实例的时候,我们会这样:

    Class a = new Class(parameter);

    当我们创建一个Integer对象时,却可以这样:

    Integer i = 100; (注意:不是 int i = 100; )

    实际上,执行上面那句代码的时候,系统为我们执行了:Integer i = Integer.valueOf(100); (感谢@黑面馒头 和 @MayDayIT 的提醒)

    此即基本数据类型的自动装箱功能。

    基本数据类型与对象的差别

    基本数据类型不是对象,也就是使用int、double、boolean等定义的变量、常量。

    基本数据类型没有可调用的方法。

    eg: int t = 1; t. 后面是没有方法滴。

    Integer t =1; t. 后面就有很多方法可让你调用了。

    什么时候自动装箱

    例如:Integer i = 100;

    相当于编译器自动为您作以下的语法编译:Integer i = Integer.valueOf(100);

    什么时候自动拆箱

      自动拆箱(unboxing),也就是将对象中的基本数据从对象中自动取出。如下可实现自动拆箱:

     Integer i = 10; //装箱 
     int t = i; //拆箱,实际上执行了 int t = i.intValue();

     在进行运算时,也可以进行拆箱。

     Integer i = 10; 
     System.out.println(i++);

    Integer的自动装箱

    //在-128~127 之外的数
     Integer i1 =200;  
     Integer i2 =200;          
     System.out.println("i1==i2: "+(i1==i2));                   
     // 在-128~127 之内的数
     Integer i3 =100;  
     Integer i4 =100;  
     System.out.println("i3==i4: "+(i3==i4));

       输出的结果是:

        i1==i2: false
        i3==i4: true

    说明:

    equals() 比较的是两个对象的值(内容)是否相同。

    “==” 比较的是两个对象的引用(内存地址)是否相同,也用来比较两个基本数据类型的变量值是否相等。

    前面说过,int 的自动装箱,是系统执行了 Integer.valueOf(int i),先看看Integer.java的源码:

    public static Integer valueOf(int i) {
        if(i >= -128 && i <= IntegerCache.high)  // 没有设置的话,IngegerCache.high 默认是127
            return IntegerCache.cache[i + 128];
        else
            return new Integer(i);
    }

    对于–128到127(默认是127)之间的值,Integer.valueOf(int i) 返回的是缓存的Integer对象(并不是新建对象)

    所以范例中,i3 与 i4实际上是指向同一个对象。

    而其他值,执行Integer.valueOf(int i) 返回的是一个新建的 Integer对象,所以范例中,i1与i2 指向的是不同的对象。

    当然,当不使用自动装箱功能的时候,情况与普通类对象一样,请看下例:

     Integer i3 =new Integer(100); 
     Integer i4 =new Integer(100); 
     System.out.println("i3==i4: "+(i3==i4));//显示false

    String 的拆箱装箱

    先看个例子:

     String str1 ="abc";
     String str2 ="abc";
     System.out.println(str2==str1); //输出为 true 
     System.out.println(str2.equals(str1)); //输出为 true 
    
     String str3 =new String("abc");
     String str4 =new String("abc"); 
     System.out.println(str3==str4); //输出为 false 
     System.out.println(str3.equals(str4)); //输出为 true

      这个怎么解释呢?貌似看不出什么。那再看个例子。

     String d ="2"; 
     String e ="23";
     e = e.substring(0, 1);
     System.out.println(e.equals(d)); //输出为 true 
     System.out.println(e==d); //输出为 false

    第二个例子中,e的初始值与d并不同,因此e与d是各自创建了个对象,(e==d)为false 。
    同理可知,第一个例子中的str3与str4也是各自new了个对象,而str1与str2却是引用了同一个对象。

    展开全文
  • 主要为大家详细介绍了Java自动拆装箱的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • java中自动拆装箱

    2017-03-18 17:29:05
    4.2 自动装箱和拆箱 基本数据(Primitive)类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。虽然为您打包基本数据类型提供了...在Java中,所有要处理的东西几乎都是对象(Object),例如之前所

    4.2 自动装箱和拆箱

    基本数据(Primitive)类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。虽然为您打包基本数据类型提供了方便,但提供方便的同时表示隐藏了细节,建议在能够区分基本数据类型与对象的差别时再使用。

    4.2.1 autoboxing和unboxing

    在Java中,所有要处理的东西几乎都是对象(Object),例如之前所使用的Scanner是对象,字符串(String)也是对象,之后还会看到更多的对象。然而基本(Primitive)数据类型不是对象,也就是您使用int、double、boolean等定义的变量,以及您在程序中直接写下的字面常量。

    在前一个小节中已经大致看到了操作对象的方便性,而使用Java有一段时间的人都知道,有时需要将基本数据类型转换为对象。例如使用Map对象要操作put()方法时,需要传入的参数是对象而不是基本数据类型。

    要使用打包类型(Wrapper Types)才能将基本数据类型包装为对象,前一个小节中您已经知道在J2SE 5.0之前,要使用以下语句才能将int包装为一个Integer对象:

    Integer integer = new Integer(10);

    在 J2SE 5.0之后提供了自动装箱的功能,您可以直接使用以下语句来打包基本数据类型:

    Integer integer = 10;

    在进行编译时,编译器再自动根据您写下的语句,判断是否进行自动装箱动作。在上例中integer参考的会是Integer类的实例。同样的动作可以适用于 boolean、byte、short、char、long、float、double等基本数据类型,分别会使用对应的打包类型(Wrapper Types)Boolean、Byte、Short、Character、Long、Float或Double。下面直接使用自动装箱功能来改写范例4.4。

    Ü 范例4.5  AutoBoxDemo.java

    public class AutoBoxDemo {

        public static void main(String[] args) {

            Integer data1 = 10;

            Integer data2 = 20;

           

            // 转为double值再除以3

            System.out.println(data1.doubleValue() / 3);

            // 进行两个值的比较

            System.out.println(data1.compareTo(data2));

        }

    }

    程序看来简洁了许多,data1与data2在运行时就是Integer的实例,可以直接进行对象操作。执行的结果如下:

    3.3333333333333335

    –1

    自动装箱运用的方法还可以如下:

    int i = 10; 
    Integer integer = i;

    也可以使用更一般化的java.lang.Number类来自动装箱。例如:

    Number number = 3.14f;

    3.14f会先被自动装箱为Float,然后指定给number。

    从J2SE 5.0开始可以自动装箱,也可以自动拆箱(unboxing),也就是将对象中的基本数据形态信息从对象中自动取出。例如下面这样写是可以的:

    Integer fooInteger = 10;
    int fooPrimitive = fooInteger;

    fooInteger引用至自动装箱为Integer的实例后,如果被指定给一个int类型的变量fooPrimitive,则会自动变为int类型再指定给fooPrimitive。在运算时,也可以进行自动装箱与拆箱。例如:

    Integer i = 10;
    System.out.println(i + 10);
    System.out.println(i++);

    上例中会显示20与10,编译器会自动进行自动装箱与拆箱,也就是10会先被装箱,然后在i + 10时会先拆箱,进行加法运算;i++该行也是先拆箱再进行递增运算。再来看一个例子:

    Boolean boo = true;
    System.out.println(boo && false);

    同样的boo原来是Boolean的实例,在进行AND运算时,会先将boo拆箱,再与false进行AND运算,结果会显示false。

    4.2.2 小心使用 boxing

    自动装箱与拆箱的功能事实上是编译器来帮您的忙,编译器在编译时期依您所编写的语法,决定是否进行装箱或拆箱动作。例如:

    Integer i = 100;

    相当于编译器自动为您作以下的语法编译:

    Integer i = new Integer(100);

    所以自动装箱与拆箱的功能是所谓的“编译器蜜糖”(Compiler Sugar),虽然使用这个功能很方便,但在程序运行阶段您得了解Java的语义。例如下面的程序是可以通过编译的:

    Integer i = null;
    int j = i;

    这样的语法在编译时期是合法的,但是在运行时期会有错误,因为这种写法相当于:

    Integer i = null;
    int j = i.intValue();

    null表示i没有参考至任何的对象实体,它可以合法地指定给对象参考名称。由于实际上i并没有参考至任何的对象,所以也就不可能操作intValue()方法,这样上面的写法在运行时会出现NullPointerException错误。

    自动装箱、拆箱的功能提供了方便性,但隐藏了一些细节,所以必须小心。再来看范例4.6,您认为结果是什么呢?

    Ü 范例4.6  AutoBoxDemo2.java

    public class AutoBoxDemo2 {

        public static void main(String[] args) {

            Integer i1 = 100;

            Integer i2 = 100;

            if (i1 == i2)

                System.out.println("i1 == i2");

            else

                System.out.println("i1 != i2");

        }

    }

    从自动装箱与拆箱的机制来看,可能会觉得结果是显示i1 == i2,您是对的。那么范例4.7的这个程序,您觉得结果是什么?

    Ü 范例4.7  AutoBoxDemo3.java

    public class AutoBoxDemo3 {

        public static void main(String[] args) {

            Integer i1 = 200;

            Integer i2 = 200;

            if (i1 == i2)

                System.out.println("i1 == i2");

            else

                System.out.println("i1 != i2");

        }

    }

    结果是显示i1 != i2,这有些令人惊讶,两个范例语法完全一样,只不过改个数值而已,结果却相反。

    其实这与==运算符的比较有关,在第3章中介绍过==是用来比较两个基本数据类型的变量值是否相等,事实上==也用于判断两个对象引用名称是否参考至同一个对象。

    在自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用,所以范例4.6中使用==进行比较时,i1 与 i2实际上参考至同一个对象。如果超过了从–128到127之间的值,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个Integer对象,所以范例4.7使用==进行比较时,i1与i2参考的是不同的对象。

    所以不要过分依赖自动装箱与拆箱,您还是必须知道基本数据类型与对象的差异。范例4.7最好还是依正规的方式来写,而不是依赖编译器蜜糖(Compiler Sugar)。例如范例4.7必须改写为范例4.8才是正确的。

    Ü 范例4.8  AutoBoxDemo4.java

    public class AutoBoxDemo4 {

        public static void main(String[] args) {

            Integer i1 = 200;

            Integer i2 = 200;

            if (i1.equals(i2))

                System.out.println("i1 == i2");

            else

                System.out.println("i1 != i2");

        }

    }

    结果这次是显示i1 == i2。使用这样的写法,相信也会比较放心一些,对于这些方便但隐藏细节的功能到底要不要用呢?基本上只有一个原则:如果您不确定就不要用。

    http://blog.csdn.net/yudongy2008/article/details/6045478

    展开全文
  • 什么是Java中自动拆装箱

    万次阅读 多人点赞 2018-09-03 12:47:37
    本文主要介绍Java中自动拆箱与自动装箱的有关知识。 1、基本数据类型 基本类型,或者叫做内置类型,是Java中不同于类(Class)的特殊类型。它们是我们编程使用最频繁的类型。 Java是一种强类型语言,第一次...

    个人博客请访问 http://www.x0100.top 

    本文主要介绍Java中的自动拆箱与自动装箱的有关知识。

     

    1、基本数据类型

     

    基本类型,或者叫做内置类型,是Java中不同于类(Class)的特殊类型。它们是我们编程中使用最频繁的类型。

    Java是一种强类型语言,第一次申明变量必须说明数据类型,第一次变量赋值称为变量的初始化。

    Java基本类型共有八种,基本类型可以分为三类:

    字符类型char

    布尔类型boolean

    整数类型byteshortintlong

    浮点数类型floatdouble

    Java中的数值类型不存在无符号的,它们的取值范围是固定的,不会随着机器硬件环境或者操作系统的改变而改变。

    实际上,Java中还存在另外一种基本类型void,它也有对应的包装类java.lang.Void,不过我们无法直接对它们进行操作。

    基本数据类型有什么好处

    我们都知道在Java语言中,new一个对象是存储在堆里的,我们通过栈中的引用来使用这些对象;所以,对象本身来说是比较消耗资源的。

    对于经常用到的类型,如int等,如果我们每次使用这种变量的时候都需要new一个Java对象的话,就会比较笨重。

    所以,和C++一样,Java提供了基本数据类型,这种数据的变量不需要使用new创建,他们不会在堆上创建,而是直接在栈内存中存储,因此会更加高效。

    整型的取值范围

    Java中的整型主要包含byteshortintlong这四种,表示的数字范围也是从小到大的,之所以表示范围不同主要和他们存储数据时所占的字节数有关。

    先来个简答的科普,1字节=8位(bit)。java中的整型属于有符号数。

    先来看计算中8bit可以表示的数字:

    最小值:10000000 (-128)(-2^7)
    最大值:01111111(127)(2^7-1)
    

    整型的这几个类型中,

    • byte:byte用1个字节来存储,范围为-128(-2^7)到127(2^7-1),在变量初始化的时候,byte类型的默认值为0。

    • short:short用2个字节存储,范围为-32,768 (-2^15)到32,767 (2^15-1),在变量初始化的时候,short类型的默认值为0,一般情况下,因为Java本身转型的原因,可以直接写为0。

    • int:int用4个字节存储,范围为-2,147,483,648 (-2^31)到2,147,483,647 (2^31-1),在变量初始化的时候,int类型的默认值为0。

    • long:long用8个字节存储,范围为-9,223,372,036,854,775,808 (-2^63)到9,223,372,036, 854,775,807 (2^63-1),在变量初始化的时候,long类型的默认值为0L或0l,也可直接写为0。

    超出范围怎么办

    上面说过了,整型中,每个类型都有一定的表示范围,但是,在程序中有些计算会导致超出表示范围,即溢出。如以下代码:

    int i = Integer.MAX_VALUE;
    int j = Integer.MAX_VALUE;
    
    int k = i + j;
    System.out.println("i (" + i + ") + j (" + j + ") = k (" + k + ")");
    

    输出结果:i (2147483647) + j (2147483647) = k (-2)

    这就是发生了溢出,溢出的时候并不会抛异常,也没有任何提示。所以,在程序中,使用同类型的数据进行运算的时候,一定要注意数据溢出的问题。

     

    2、包装类型

    Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class)。

    包装类均位于java.lang包,包装类和基本数据类型的对应关系如下表所示

    基本数据类型包装类
    byteByte
    booleanBoolean
    shortShort
    charCharacter
    intInteger
    longLong
    floatFloat
    doubleDouble

    在这八个类名中,除了Integer和Character类以后,其它六个类的类名和基本数据类型一致,只是类名的第一个字母大写即可。

    为什么需要包装类

    很多人会有疑问,既然Java中为了提高效率,提供了八种基本数据类型,为什么还要提供包装类呢?

    这个问题,其实前面已经有了答案,因为Java是一种面向对象语言,很多地方都需要使用对象而不是基本数据类型。比如,在集合类中,我们是无法将int 、double等类型放进去的。因为集合的容器要求元素是Object类型。

    为了让基本类型也具有对象的特征,就出现了包装类型,它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。

     

    3、拆箱与装箱

     

    那么,有了基本数据类型和包装类,肯定有些时候要在他们之间进行转换。比如把一个基本数据类型的int转换成一个包装类型的Integer对象。

    我们认为包装类是对基本类型的包装,所以,把基本数据类型转换成包装类的过程就是打包装,英文对应于boxing,中文翻译为装箱。

    反之,把包装类转换成基本数据类型的过程就是拆包装,英文对应于unboxing,中文翻译为拆箱。

    在Java SE5之前,要进行装箱,可以通过以下代码:

    Integer i = new Integer(10);
    

     

    4、自动拆箱与自动装箱

     

    在Java SE5中,为了减少开发人员的工作,Java提供了自动拆箱与自动装箱功能。

    自动装箱: 就是将基本数据类型自动转换成对应的包装类。

    自动拆箱:就是将包装类自动转换成对应的基本数据类型。

    Integer i =10;  //自动装箱
    int b= i;     //自动拆箱
    

    Integer i=10 可以替代 Integer i = new Integer(10);,这就是因为Java帮我们提供了自动装箱的功能,不需要开发者手动去new一个Integer对象。

     

    5、自动装箱与自动拆箱的实现原理

     

    既然Java提供了自动拆装箱的能力,那么,我们就来看一下,到底是什么原理,Java是如何实现的自动拆装箱功能。

    我们有以下自动拆装箱的代码:

    public static  void main(String[]args){
        Integer integer=1; //装箱
        int i=integer; //拆箱
    }
    

    对以上代码进行反编译后可以得到以下代码:

    public static  void main(String[]args){
        Integer integer=Integer.valueOf(1); 
        int i=integer.intValue(); 
    }
    

    从上面反编译后的代码可以看出,int的自动装箱都是通过Integer.valueOf()方法来实现的,Integer的自动拆箱都是通过integer.intValue来实现的。如果读者感兴趣,可以试着将八种类型都反编译一遍 ,你会发现以下规律:

    自动装箱都是通过包装类的valueOf()方法来实现的.自动拆箱都是通过包装类对象的xxxValue()来实现的。

     

    6、哪些地方会自动拆装箱

     

    我们了解过原理之后,在来看一下,什么情况下,Java会帮我们进行自动拆装箱。前面提到的变量的初始化和赋值的场景就不介绍了,那是最简单的也最容易理解的。

    我们主要来看一下,那些可能被忽略的场景。

    场景一、将基本数据类型放入集合类

    我们知道,Java中的集合类只能接收对象类型,那么以下代码为什么会不报错呢?

    List<Integer> li = new ArrayList<>();
    for (int i = 1; i < 50; i ++){
        li.add(i);
    }
    

    将上面代码进行反编译,可以得到以下代码:

    List<Integer> li = new ArrayList<>();
    for (int i = 1; i < 50; i += 2){
        li.add(Integer.valueOf(i));
    }
    

    以上,我们可以得出结论,当我们把基本数据类型放入集合类中的时候,会进行自动装箱。

    场景二、包装类型和基本类型的大小比较

    有没有人想过,当我们对Integer对象与基本类型进行大小比较的时候,实际上比较的是什么内容呢?看以下代码:

    Integer a=1;
    System.out.println(a==1?"等于":"不等于");
    Boolean bool=false;
    System.out.println(bool?"真":"假");
    

    对以上代码进行反编译,得到以下代码:

    Integer a=1;
    System.out.println(a.intValue()==1?"等于":"不等于");
    Boolean bool=false;
    System.out.println(bool.booleanValue?"真":"假");
    

    可以看到,包装类与基本数据类型进行比较运算,是先将包装类进行拆箱成基本数据类型,然后进行比较的。

    场景三、包装类型的运算

    有没有人想过,当我们对Integer对象进行四则运算的时候,是如何进行的呢?看以下代码:

    Integer i = 10;
    Integer j = 20;
    
    System.out.println(i+j);
    

    反编译后代码如下:

    Integer i = Integer.valueOf(10);
    Integer j = Integer.valueOf(20);
    System.out.println(i.intValue() + j.intValue());
    

    我们发现,两个包装类型之间的运算,会被自动拆箱成基本类型进行。

    场景四、三目运算符的使用

    这是很多人不知道的一个场景,作者也是一次线上的血淋淋的Bug发生后才了解到的一种案例。看一个简单的三目运算符的代码:

    boolean flag = true;
    Integer i = 0;
    int j = 1;
    int k = flag ? i : j;
    

    很多人不知道,其实在int k = flag ? i : j;这一行,会发生自动拆箱。反编译后代码如下:

    boolean flag = true;
    Integer i = Integer.valueOf(0);
    int j = 1;
    int k = flag ? i.intValue() : j;
    

    这其实是三目运算符的语法规范:当第二,第三位操作数分别为基本类型和对象时,其中的对象就会拆箱为基本类型进行操作。

    因为例子中,flag ? i : j;片段中,第二段的i是一个包装类型的对象,而第三段的j是一个基本类型,所以会对包装类进行自动拆箱。如果这个时候i的值为null,那么久会发生NPE。(自动拆箱导致空指针异常

    场景五、函数参数与返回值

    这个比较容易理解,直接上代码了:

    //自动拆箱
    public int getNum1(Integer num) {
     return num;
    }
    //自动装箱
    public Integer getNum2(int num) {
     return num;
    }
    

     

    7、自动拆装箱与缓存

     

    Java SE的自动拆装箱还提供了一个和缓存有关的功能,我们先来看以下代码,猜测一下输出结果:

    public static void main(String... strings) {
    
        Integer integer1 = 3;
        Integer integer2 = 3;
    
        if (integer1 == integer2)
            System.out.println("integer1 == integer2");
        else
            System.out.println("integer1 != integer2");
    
        Integer integer3 = 300;
        Integer integer4 = 300;
    
        if (integer3 == integer4)
            System.out.println("integer3 == integer4");
        else
            System.out.println("integer3 != integer4");
    
    }
    

    我们普遍认为上面的两个判断的结果都是false。虽然比较的值是相等的,但是由于比较的是对象,而对象的引用不一样,所以会认为两个if判断都是false的。

    在Java中,==比较的是对象应用,而equals比较的是值。

    所以,在这个例子中,不同的对象有不同的引用,所以在进行比较的时候都将返回false。奇怪的是,这里两个类似的if条件判断返回不同的布尔值。

    上面这段代码真正的输出结果:

    integer1 == integer2
    integer3 != integer4
    

    原因就和Integer中的缓存机制有关。在Java 5中,在Integer的操作上引入了一个新功能来节省内存和提高性能。整型对象通过使用相同的对象引用实现了缓存和重用。

    适用于整数值区间-128 至 +127。

     

    只适用于自动装箱。使用构造函数创建对象不适用。

    具体的代码实现可以阅读Java中整型的缓存机制一文,这里不再阐述。

    我们只需要知道,当需要进行自动装箱时,如果数字在-128至127之间时,会直接使用缓存中的对象,而不是重新创建一个对象。

    其中的javadoc详细的说明了缓存支持-128到127之间的自动装箱过程。最大值127可以通过-XX:AutoBoxCacheMax=size修改。

    实际上这个功能在Java 5中引入的时候,范围是固定的-128 至 +127。后来在Java 6中,可以通过java.lang.Integer.IntegerCache.high设置最大值。

    这使我们可以根据应用程序的实际情况灵活地调整来提高性能。到底是什么原因选择这个-128到127范围呢?因为这个范围的数字是最被广泛使用的。 在程序中,第一次使用Integer的时候也需要一定的额外时间来初始化这个缓存。

    在Boxing Conversion部分的Java语言规范(JLS)规定如下:

    如果一个变量p的值是:

    -128至127之间的整数(§3.10.1)
    
    true 和 false的布尔值 (§3.10.3)
    
    ‘\u0000’至 ‘\u007f’之间的字符(§3.10.4)
    

    范围内的时,将p包装成a和b两个对象时,可以直接使用a==b判断a和b的值是否相等。

     

    8、自动拆装箱带来的问题

     

    当然,自动拆装箱是一个很好的功能,大大节省了开发人员的精力,不再需要关心到底什么时候需要拆装箱。但是,他也会引入一些问题。

    包装对象的数值比较,不能简单的使用==,虽然-128到127之间的数字可以,但是这个范围之外还是需要使用equals比较。

     

    前面提到,有些场景会进行自动拆装箱,同时也说过,由于自动拆箱,如果包装类对象为null,那么自动拆箱时就有可能抛出NPE。

     

    如果一个for循环中有大量拆装箱操作,会浪费很多资源。

    更多精彩内容扫描下方二维码进入网站。。。。。

    关注微信公众号。。。。。

     

     

     

     

    展开全文
  • 因为,在java中new一个对象是存储在堆里的,对于 我们经常操作的数据类型,每次创建对象这样太消耗资源,因此java提供了8个基本数据类型,存储在栈里。用起来更方便。 自动类型转换 转换前的数据类型的位数低于转换...

    为什么会有基本数据类型?

    因为,在java中new一个对象是存储在堆里的,对于 我们经常操作的数据类型,每次创建对象这样太消耗资源,因此java提供了8个基本数据类型,存储在栈里。用起来更方便。
    自动类型转换
    转换前的数据类型的位数低于转换后的数据类型。
    例如: short数据类型的位数为16位,就可以自动转换位数为32的int类型,同样float数据类型的位数为32,可以自动转换为64位的double类型。

                   自动类型转换
    低  ------------------------------------>  高byte,short,char—> int —> long—> float —> double 
    数据类型转换必须满足如下规则:
    不能对boolean类型进行类型转换。
    不能把对象类型转换成不相关类的对象。
    由大到小会丢失精度:在把容量大的类型转换为容量小的类      型时必须使用强制类型转换。
    

    强制类型转换

    条件:

        转换的数据类型必须是兼容的。
    

    存在问题:

        转换过程中可能导致溢出或损失精度,例如:
    
    int i =128;   
    byte b = (byte)i;//-128
    
    因为 byte 类型是 8 位,最大值为127,所以当 int 强制转换为 byte 类型时,值 128 时候就会导致溢出。
    

    浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入,例如:
    (int)23.7 == 23;
    (int)-45.89f == -45

    自动拆装箱出现原因:就是让基本数据类型的变量具有类中对象的特征。

    基本数据类型,使用起来非常方便,但是没有对应的方法来操作这些基本类型的数据,可以使用一个类,把基本数据类型的数据装起来,这个类叫做包装类(wrapper)。这样我们可以调用类中的方法。

    开发中,用的最多的是字符串变为基本数据类型。

    8种基本数据类型对应包装类:可以看到除了int和char类型,其它都是首字母大写。

    基本数据类型 包装类
    byte Byte
    short Short
    int Integer
    long Long
    float Float
    double Double
    char Character
    boolean Boolean
    装箱

         即对基本类型进行包装,基本类型->包装类
         通过包装类的构造器实现(jdk1.5之前)
         Integer t = new Integer(10);
         通过字符串参数构造包装类对象
         Float f = new Float("4.56");
         Long l = new Long("wer");//NumberFormatException
         自动装箱(jdk1.5之后)
         Integer i = 100;替代了 Integer i = new In因为Java帮我们提供了自动装箱的功能,不需要开发者手动去
         new一个Integer对象。
         Integer i = 100;//自动装箱
         //相当于编译器自动作以下的语法编译:Integer i =Integer.valueOf(100);
    

    拆箱

     包装类->基本类型
     调用包装类中的.xxxValue()方法
     Integer t = 128; // 此时t就是一个包装类
     System.out.println(t.intValue());//128
    

    自动拆箱

     Integer i = 10; //自动装箱 
     int t = i; //自动拆箱,实际上执行了 int t = i.intValue();
     自动装箱和自动拆箱的实现原理#
     Integer integer = 1;
     //自动装箱,相当于Integer integer = Integer.valueOf(1);
     int i = integer;
     //自动拆箱,相当于int i = integer.intValue();
     对于上面的代码,Java是怎么做的呢?
     自动装箱:调用valueOf()方法将原始类型值转换成对象  自动拆箱:调用intValue()方法,其他的(xxxValue())这类的方法将对象转换成原始类型值。
    
    public void testInteger(){
        Integer i = 10;
        int i1 = 10;
        System.out.println(i == i1); //true
          Integer i2 = 300;
        int i3 = 300;
        System.out.println(i2 == i3); //true
    }
    
    
    public void testInteger2(){
        System.out.println("Integer与Integer比较");  Integer i6 = 128;
        Integer i7 = 128;
        System.out.println(i6 == i7);//false
        // i6自动装箱产生的Integer对象,大小超过了-128——127的范围,这里会直接创建该对象:new Integer(128)
        // i7同理。它们在堆中的地址是不同的,因此false.
    
        Integer i4 = 1;
        Integer i5 = 1;
        System.out.println(i4 == i5); //true
        // i4、i5都是从IntegerCache中取出来的对象,故true;
    
        Integer i8 = 127;
        Integer i9 = 127;
        System.out.println(i8 == i9);//true
        // i8、i9都是从IntegerCache中取出来的对象,故true;
    
        Integer i10 = new Integer(127);
        Integer i11 = 127;
        System.out.println(i10 == i11); //false
        // i10是创建的一个Integer的对象,取值是127
        // i11是进行自动装箱后生成的Integer对象,在-128——127之间,是直接从缓存IntegerCache中取出来的对象
        // i10是自己new出来的对象,i11是从IntegerCache中取的对象,地址不同,故false.
    
        Integer i12 = new Integer(128);
        Integer i13 = 128;
        System.out.println(i12 == i13);//false
        // 说明:i12是创建的一个Integer的对象,取值是128
        // i13 是进行自动装箱的实例,这里超出了-128——127的范围,创建了新的Integer对象。
        // 二者存储在堆中,分配的地址不同,因此用==判断时,由于对象的地址不同,所以false.
    }
    }
    
    展开全文
  • 主要介绍了Java三目运算隐藏的自动拆装箱,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
  • Java自动拆装箱

    2019-06-02 14:24:08
    什么是自动拆装箱Java 语言支持的 8 基本数据类型是: 整型:byte short int long 浮点型:float double 布尔型:boolean 字符型:char 自动装箱是 Java 编译器在基本数据类型和对应的对象包装类型之间...
  • * 自动装箱 *int类型 ---------------------->自动转换引用类型 :Integer **/ public class IntegerDemo3 { public static void main(String[] args) { //定义一个Integer类型 Integer i = new ...
  • JAVA自动拆装箱

    千次阅读 多人点赞 2016-02-23 11:19:33
    Java中,一切都以对象作为基础,但是基本类型并不是对象,如果想以对象的方式使用这8基本类型,可以将它们转换为对应的包装类型。基本类型和包装类型的对应: int(4字节) Integer byte...
  • java自动拆装箱

    2017-03-05 20:09:07
    装箱: 把基本的数据类型转化为包装类 拆箱:把包装类转化成基本数据类型 ...自动装箱: Integer i=10; 自动拆箱 int m=i; jdk是会向下兼容的 -比如 jdk1.4 里面写的代码,这个时候到5.0也可运行
  • Integer 类在对象包装了一个基本类型 int 的值, 该类提供了多个方法,能在 int 类型和 String 类型之间互相转换, 还提供了处理 int 类型时非常有用的其他一些常量和方法 B:构造方法 public Integer(int value) ...
  • 但在 Java 不能定义基本类型对象,为了能将基本类型视为对象处理,并能连接相关方法,Java 为每个基本数据类型都提供了包装类,如 int 型数值的包装类 Integer,boolean 型数值的包装类 Boolean 等。这样便可以把...
  • 文章目录JDK.8自动拆装箱1.构造方法2.自动拆装箱3.Integer基本方法4.Integer与int之间的==关系 JDK.8自动拆装箱 1.构造方法 package ContainerLoading; /** * Integer应用类型的构造方法 * public Integer(int ...
  • 主要给大家介绍了关于Java基础教程之基本类型数据类型、包装类及自动拆装箱的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
  • 自动拆装箱在Java5(就是Java1.5,后边改了命名)时被引入,自动装箱就是Java自动将基础类型值转换成对应的包装类对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个...
  • 深入理解Java包装类与自动拆装箱

    千次阅读 2020-06-21 22:36:30
    你真的理解Java包装类和自动拆装箱吗?有些知识你绝对不知道!
  • 我们知道,Java有8大基本数据类型,4整2浮1符1布。 我们在实际开发,除了使用到数据的值之外,还会涉及到对数据的操作。根据“面向对象”编程的思想,这些常见的操作被抽象成方法,封装到了一个类,一个基本...
  • 继续向下看吧~Java中的数据类别目前Java中的数据类别分为两种,一种是primitive(原生类型),另一种就是object(对象类型)。提示:从jdk13开始,会引进第三种类型,名为ValueType,设计理念是结合了primitive和...
  • Java中关于自动拆装箱

    2021-06-17 17:12:12
    Java 语言是一个面向对象的语言,但是 Java 的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本...
  • java 自动拆装箱特性

    多人点赞 2021-09-14 16:00:54
    自动拆装箱的运用3.一些典型举例 一、自动装拆箱是什么? 有时,需要将int这样的基本类型转换为对象。所有的基本类型都有一个与之对应的类,例如 Integer类对应基本类型int。通常,这些类被称为包装器。 这些...
  • 本文主要介绍Java中自动拆箱与自动装箱的有关知识。 一、基本数据类型 基本类型,或者叫做内置类型,是Java中不同于类(Class)的特殊类型。它们是我们编程使用最频繁的类型。 Java是一种强类型语言,第一次...
  • 描述java自动拆装箱及享元设计模式 文件为视频教学 请勿用于商业用途
  • 每当需要一个值时,装箱对象的值就会被自动提取出来,不需要调用对象的方法  例如:Integer a=100;  int b=a;   //直接将引用对象赋给一个基本数据类型的变量 int b =a.intValue(); 此过程为手动拆箱    
  • Java自动拆装箱

    2021-03-22 22:33:29
    JDK 1.5开始增加了自动拆装箱机制,Java保留了一些原始的基本数据类型,但由于Java是强面向对象语言,数据类型当然也应该设置成对象才是,所以Java也推出了对于基本数据类型的对应的对象,将基本数据类型转换为对象...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,121
精华内容 4,048
关键字:

java中的自动拆装箱

java 订阅