java常用类源代码探究(二):装箱类

java提供了8中基本数据类型

整型:byte,short,int,long

浮点型:double,float

字符型:char         布尔型:boolean

但是java是一门面向对象的语言,如何让这些类型定义的对象可以调用类定义的方法呢,java机制提供了一些类型对其进行了包装提供了8种装类,其一一对应关系为:

byte Byte
shortShort
intInteger
longLong
doubleDouble
floatFloat
charChareacter
booleanBoolean

那么java是如如何提供装箱类的事项的呢,我们一起来查看他们的源代码这里以Integer为例


其继承了Number类并且实现了Comparable接口:

其中Number类是数值类型相关的包装类的一个父类包括(Byte,Short,Integer等等),Number类是一个抽象定义了一些基本的数值转换方法,这是一种设计模式:模板函数设计模式;

Comparable接口实现其compareTo()方法,用于两个数值的比较。

Integer类设计的分析

第一部分:String<->Integer  String与Integer间的转化

1.Integer中的属性

Integer类型数据可表示的最小值-2147483648

public static final int   MIN_VALUE = 0x80000000;

Integer类型数据可表示的最大值2147483647

public static final int   MAX_VALUE = 0x7fffffff;

获取Integer的原生类名

public static final Class<Integer>  TYPE = (Class<Integer>) Class.getPrimitiveClass("int");

然后定义了一个char型常静态数组digits

里面面试Integer对象所有可能用到的字符‘0’-’9‘,‘a'-’z',用于字符串的解析成Integer


2.Integer中的方法

        在Integer类中没有首先定义构造函数,而是定义了一些数制转化的方法主要基于toUnsignedString(int i, int shift)方法,shift是指转到哪个进制

        然后是Integer的一些数制解析方法,比如toString(),parseInt(String)字符串与Integer间的转化


第二部分:Integer本生类的设计(属性,构造函数。。。)

1.Integer中的属性:private final int value;一个常量属性,说明Integer是一个不可变类与String类类似,将属性放在java内存的常量区

   这样的设计会使每次更新一个Integer类型的代价很大,需要将常量区原来的内存销毁重新创建一个常量区内存,为了提高Integer类操作运算的性能,Integer采用了缓存的方法,我们看它从源代码中如何实现:

   首先在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) {
                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);
            }
            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() {}
    }
再看javadoc中的描述:缓存用于对象值的自动装箱包括-128-127之间的值(默认)

缓存当第一次使用的时候被初始化,缓存数组的容量由-XX:AutoBoxCacheMax=<size> 选择。

在虚拟机初始化的时候,Integer缓存空间的最大值被设置并且被保存在sun.misc.VM 类的私有系统属性中

再结合自动装箱拆箱时用到的valueOf(int i)方法

public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
当i的值再缓存中时则Integer对应的值就是缓存中的值,否则重新构造一个Integer类对象。


通过以上的分析就可以解释一下程序的输出了

  1. public class Test03 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;  
  5.           
  6.         System.out.println(f1 == f2);  
  7.         System.out.println(f3 == f4);  
  8.     }  
  9. }  

第一个输出为true,第二个输出为false,就是因为在拆箱后一个是缓存中的对象,一个是new出来的对象。


2.构造函数

 (1)public Integer(int value) {
        this.value = value;
    }//直接传一个int整形数值

 (2)public Integer(String s) throws NumberFormatException {
        this.value = parseInt(s, 10);
    }//传一个String类型值,将其转化为10进制


3.重写Object中的方法

   其中toString()方法的实现,在方法内调用重载的方法toString(int i)

   通过计算其位数来输出各位数字

   hashCode()方法返回的就是value值

   equals(Object obj)方法比较的是两个值的真实值


4.其他

   实现Comparable接口的compareTo(Integer anotherInteger)方法

   重写Number类的数值类型转化方法

   还有一些复杂的进制换算方法,方法的实现涉及到复杂的位运算,这里就不一一介绍了




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值