zoukankan      html  css  js  c++  java
  • java 自动装箱与拆箱 (基本类型与包装类型)

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

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

     Class a = new Class(parameter);

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

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

    实际上,执行上面那句代码的时候,系统为我们执行了:Integer i = new Integer(100); 此即基本数据类型的自动装箱功能。

    java 基本数据类型与封装器类

     因为java中数字不是对象。Java语言的数据类型有两大类:一类是简单类型,也称主要类型(Primitive),另一类是引用类型(Reference)。简单类型变量中存储的是具体的值,而引用类型的变量中存储的是对象的引用。

     Java决定了每种简单类型的大小。这些大小并不随着机器结构的变化而变化。这种大小的不可更改正是Java程序具有很强移植能力的原因之一。

      下表列出了Java中定义的简单类型、占用二进制位数及对应的封装器类。

      表 Java中的简单类型

    简单类型 boolean byte char short int long float double void
    二进制位数 1 8 16 16 32 64 32 64 --
    封装器类 Boolean Byte Character Short Integer Long Float Double Void

    注意int 和 char 封装器类分别是Integer和Character.

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

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

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

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

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

     

    什么时候自动装箱

      例如:Integer i = 100;

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

    什么时候自动拆箱

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

    1 Integer i =10; //装箱
    2  int t = i; //拆箱

    在进行运算时,也可以进行自动装箱与拆箱。 (即在表达式中自动装箱与拆箱有效)

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

    每个封装器类的对象都包含一个相应的基本类型的值,如Double类的对象包含double类型的值。

    Double d=29.95; //自动装箱 等同于Double d=new Double(29.95);

    double x=d; //自动拆箱,封装器对象被自动拆箱为基本类型。等同double x=d.doubleValue();

    Double e=d+1;

    是完全合法的,意味着:

    1。将d自动拆箱为一个double型数

    2加1

    3 将结果自动装箱为一个新的Double对象

    4 在 e中存储一个对新创建对象的引用

    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() 比较的是两个对象的值(内容)是否相同。

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

    Rectangle box1=new Rectangle(5,10,20,30);

    Rectangel box2=box1;

    Rectangle box3=new Rectangle(5,10,20,30);

    下面比较为真 box1==box2 

    比较为假 box1==box3;

    两个对象变量指向不同的对象,并不考虑这两个对象具有相同的内容。

    box1.equals(box3) 为真。

    在自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用,

    设计者的思路大概是,用==来进行比较,大概一般都是要比较值,但这种写法是不对的,这样吧,当对象值在一个字节以内时,比较值和比较地址的成本是一样的,那我就给你比较值,但如果值大于一个字节,比较值的成本就大过比较地址了,我就老老实实比较地址吧。

    所以范例中,i3 与 i4实际上参考至同一个对象。

    如果超过了从–128到127之间的值,被装箱后的Integer对象并不会被重用,

    即相当于每次装箱时都新建一个 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
    

      

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

    1 String d ="2";
    2 String e ="23";
    3 e = e.substring(0, 1);
    4 System.out.println(e.equals(d)); //输出为 true
    5   System.out.println(e==d); //输出为 false
     第二个例子中,e的初始值与d并不同,因此e与d是各自创建了个对象,(e==d)为false 。
    同理可知,第一个例子中的str3与str4也是各自new了个对象,而str1与str2却是引用了同一个对象。
     
    Integer i = null;//表明i没有参考至任何对象
    int j = i ;//相当于 int j = i.intValue() 这样的代码,编译时是可以通过的,因为它的语法是正确的,但在运行时,就会排除NullPointerException错误,这是由于i并没有参考至任何对象造成的。
     
     Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class),有些地方也翻译为外覆类或数据类型类。

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

    包装类对应表

    基本数据类型

    包装类

    byte

    Byte

    boolean

    Boolean

    short

    Short

    char

    Character

    int

    Integer

    long

    Long

    float

    Float

    double

    Double

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

             对于包装类说,这些类的用途主要包含两种:

                       a、作为和基本数据类型对应的类类型存在,方便涉及到对象的操作。

                       b、包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法。

             由于八个包装类的使用比较类似,下面以最常用的Integer类为例子介绍包装类的实际使用。

             1、实现int和Integer类之间的转换

    在实际转换时,使用Integer类的构造方法和Integer类内部的intValue方法实现这些类型之间的相互转换,实现的代码如下:

                       int n = 10;

                       Integer in = new Integer(100);

                       //将int类型转换为Integer类型

                       Integer in1 = new Integer(n);

                       //将Integer类型的对象转换为int类型

                       int m = in.intValue();

             2、Integer类内部的常用方法

                      在Integer类内部包含了一些和int操作有关的方法,下面介绍一些比较常用的方法:

                       a、parseInt方法

                                public static int parseInt(String s)

    该方法的作用是将数字字符串转换为int数值。在以后的界面编程中,将字符串转换为对应的int数字是一种比较常见的操作。使用示例如下:

                                         String s = “123”;

                                         int n = Integer.parseInt(s);

    则int变量n的值是123,该方法实际上实现了字符串和int之间的转换,如果字符串都包含的不是都是数字字符,则程序执行将出现异常。(说明:异常的概念将在下一章进行讲述)

    另外一个parseInt方法:

             public static int parseInt(String s, int radix)

    则实现将字符串按照参数radix指定的进制转换为int,使用示例如下:

             //将字符串”120”按照十进制转换为int,则结果为120

             int n = Integer.parseInt(“120”,10);

             //将字符串”12”按照十六进制转换为int,则结果为18

             int n = Integer.parseInt(“12”,16);

             //将字符串”ff”按照十六进制转换为int,则结果为255

             int n = Integer.parseInt(“ff”,16);

    这样可以实现更灵活的转换。

                       b、toString方法

                                public static String toString(int i)

                                该方法的作用是将int类型转换为对应的String类型。

                                使用示例代码如下:

                                         int m = 1000;

                                         String s = Integer.toString(m);

                                则字符串s的值是”1000”。

                                另外一个toString方法则实现将int值转换为特定进制的字符串:

                                         public static int parseInt(String s, int radix)

                                使用示例代码如下:

                                         int m = 20;

                                         String s = Integer.toString(m);

                                则字符串s的值是”14”。

             其实,JDK自从1.5(5.0)版本以后,就引入了自动拆装箱的语法,也就是在进行基本数据类型和对应的包装类转换时,系统将自动进行,这将大大方便程序员的代码书写。使用示例代码如下:

                       //int类型会自动转换为Integer类型

                       int m = 12;

                       Integer in = m;

                       //Integer类型会自动转换为int类型

                       int n = in;

             所以在实际使用时的类型转换将变得很简单,系统将自动实现对应的转换。

     

    java基本类型和包装类的区别

    int 是基本类型,直接存数值
    Integer是类,产生对象时用一个引用指向这个对象
    Java把内存划分成两种:一种是栈内存,另一种是堆内存
    在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配
    实际的对象是在存储堆内存中

    int i = 5;//直接在栈中分配空间
    Integer i = new Integr(5);//对象是在堆内存中,而i(引用变量)是在栈内存中
    在堆中分配的内存,由java虚拟机的自动垃圾回收器来管理.
    因为在堆中分配空间所需的时间远大于从栈中分配存储空间,所以JAVA速度比C 慢
    当需要往ArrayList,HashMap中放东西时,像int,double这种基本类型是放不进去的,因为容器都是装object的,这是就需要这些基本类型的外覆类了。Java中每种基本类型都有相应的外覆类。

    (集合类存放的都是对象的引用,而非对象本身 )


    int 和 Integer 的区别

    java 提供两种不同的类型:引用类型(或者封装类型,Warpper)和原始类型(或内置类型,Primitive)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。
    原始类型 封装类
    boolean Boolean
    char Character
    byte Byte
    short Short
    int Integer
    long Long
    float Float
    double Double
    引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的 数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。

    from:http://community.csdn.net/Expert/topic/3666/3666081.xml?temp=.9687921


    int 是基本类型,(int)(Math.Random()*100)就是一个数,可以进行加见乘除。 Integer是class ,那么 new Integer(temp)就是一个对象了,可以用到Integer这个class的方法,例如用intvalue()可以返回这个int的值

  • 相关阅读:
    nullnull聚类小文(二)
    classjavaCore Java Question List #6
    设置仿真器HJTAG ARM仿真器和MDK 联调设置
    二分图判断hdu 1829 A Bug's Life
    信息掩码游戏地图掩码相关(msk)
    导航accessibilityAndroid 抽屉导航
    算法nodehdu 2112 hdu today
    链接函数hdu 1234开门人和关门人
    分配器内存一步一步写STL:空间配置器(1)
    程序连接如何使用JLink V8 烧写程序到NOR Flash
  • 原文地址:https://www.cnblogs.com/youxin/p/2498078.html
Copyright © 2011-2022 走看看