第十一天(上)自动装箱拆箱

基本数据类型:

在实际程序使用中,程序界面上用户输入的数据都以字符串类型进行存储的.而在程序开发中,我们需呀把字符串数据抓换为指定的基本数据类型,如年龄需要转换为int类型

其实是java早年设计的一个缺陷,基本数据类型不是对象,自然不是Object的子类,需要装箱才能把数据类型变成一个类,那就可以把装箱过后的基本数据类型当做一个对象,就可以调用object子类的接口。而且基本数据类型是不可以作为形参使用的,装箱后就可以。而且在jdk1.5之后就实现了自动装箱拆箱,包装数据类型具有许多基本数据类型不具有的功能,只是装箱拆箱过程会稍稍微的影响一下效率,不过基本是看不出来的

 

八种包装类

除了Char对应Character int对应的是Integer 其他都是基本数据类型的首字母大写

这八种包装类所继承的父类不全都相同。

Integer ,Byte,Float,Double,Short,Long都属于Number类的子类,Number类本身提供了一 系列的返回

Character属于Object子类。

Boolean属于Object子类。

装箱和拆箱

扫描二维码关注公众号,回复: 2776952 查看本文章

    public static void main(String args[]){

        int a = 1;        // 基本数据类型

        Integer i = new Integer(a) ;    // 装箱:将基本数据类型变为包装类

        int temp = i.intValue()    ;// 拆箱:将一个包装类变为基本数据类型

    }

自动拆箱和装箱

Jdk1.5以后增加了自动拆箱和和自动装箱功能.

 public static void main(String args[]){

        Integer i = 1 ;    // 自动装箱成Integer

        int a = i ;            // 自动拆箱为int

    }

而不需要手动的实现

执行Integer i = 1; 
系统为我们执行了: 
Integer i = Integer.valueOf(1);

执行int a = i; 
系统为我们执行了: 
int a = i.intValue();

 

看下源码jdk1.8

    public static Integer valueOf(int i) {

        if (i >= IntegerCache.low && i <= IntegerCache.high)

            return IntegerCache.cache[i + (-IntegerCache.low)];

        return new Integer(i);

    }

对于128127之间的值,Integer.valueOf(int i) 返回的是缓存的Integer对象,超出范围的则是新new一个对象,IntegerCachenymber的一个静态内部类,就在下面

 

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 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));   

结果 false

True

简单来说就是数据在byte(-128~127)范围内,JVM不会从新new对象

对于IntegerShortByteCharacterLong这几个类的valueOf方法的实现是类似的。也就是说上面的结果都是成立的

对于DoubleFloatvalueOf方法的实现是类似的。他们没有内部类的,valueof方法与上面的不同,他们每次赋值都会在堆内存中创建新对象

 

public class Main {

    public static void main(String[] args) {

         

        Boolean i1 = false;

        Boolean i2 = false;

        Boolean i3 = true;

        Boolean i4 = true;

         

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

        System.out.println(i3==i4);

    }

}

True

True

可以去研究下boolean类的源码

 

 

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

 Integer i1 =new Integer(100);

 Integer i2 =new Integer(100);

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

False

因为他们没有触发自动装箱.也就会直接在new出来新的对象

 

Integer i = new Integer(?)Integer i =?区别

第一种不会触发自动装箱,第二种会触发

在执行效率和资源上,第二种的执行效率和内存占用会小于第二种.(而且这不是绝对的)

 

一道题

public class Main {  

    public static void main(String[] args) {  

           

        Integer a = 1;  

        Integer b = 2;  

        Integer c = 3;  

        Integer d = 3;  

        Integer e = 321;  

        Integer f = 321;  

        Long g = 3L;  

        Long h = 2L;  

           

        System.out.println(c==d);  

        System.out.println(e==f);

        System.out.println(c==(a+b));  

        System.out.println(c.equals(a+b));  

        System.out.println(g==(a+b));  

        System.out.println(g.equals(a+b));  

        System.out.println(g.equals(a+h));     

}  

}  

 

true

false

true

true

true

false

True

 

包装类的==运算在不遇到算术运算的情况下不会自动拆装

.也就是说没遇到算数运算就比较是否是指向同一对象,如果有算数运算就比较数值(触发自动装箱拆箱)

 

包装器类型equals方法不会处理数据转换的类型,

 

注意最后一个

对于a+h,先自动触发拆箱,就变成了int类型和long类型相加,这个会触发类型晋升,结果是long类型的,然后会触发装箱过程,就变成Long了。因此比较结果是true

 

倒数第二个是两个integer类型没有类型提升所以是false

 

 

类中的几个方法

Integer类的parseInt

A.  parseInt()

    int i = Integer.parseInt("2");

    System.out.println(i/2);//1

B.  parseInt(String s,int radix)

指定进制的字符串转换为十进制的整数

Public static void function(){

Int i  = IntegerInt(110,2);//前面的数是二进制的

System.out.println(i);

}

不想在写方法了感觉不知道这些常用类要掌握到什么地步,用的时候查API不就好了码 ,掌握到什么地步才行,要有多熟练.


猜你喜欢

转载自blog.51cto.com/10760006/2160255
今日推荐