Java包装类

来源:互联网 发布:js获取来源url 编辑:程序博客网 时间:2024/05/16 11:01
Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便(比如无法封装和类型相关的一些操作),为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class)。这些类封装了对特定数据类型进行处理的操作。比如需要对char类型的数据进行操作就需要使用Character类型(每个包装类都封装了对所包装类型的常用操作)。

关于各种对象的操作的学习还是需要借助于JDK和源代码,这里就举几个例子。

1.所有的数字类型的包装类都封装了该类型的最大值和最小值
以Integer为例子,在Integer的源代码中:
@Native public static final int   MIN_VALUE = 0x80000000;@Native public static final int   MAX_VALUE = 0x7fffffff;
这两个static final的属性就已经规定了Integer可以存储的数据的大小。
2.方便的类型转换
和C++对比,比如C++中用int和String进行转换的时候是使用stringstream对象或者调用使用库函数(boost库中的lexical_cast),
而java的包装类封装了类型转换的操作。实现了数据和方法的封装,这就是面向对象的优势(从这里也可以看出C++没有JAVA面向对象)。
以int和String的相互转换为例
int -> String
int i=12345;String s="";//第一种方法s=i+"";//i装箱为Integer之后调用Integer.toString然后就是String重载的+操作符,所以创建了2个String对象//第二种方法s=String.valueOf(i);//String.valueOf(int i)源码public static String valueOf(int i) {    return Integer.toString(i);}//String.valueOf()对所有的对象内置类型都重载了,如果是Object就调用Object.toString()public static String valueOf(boolean b) {    return b ? "true" : "false";}public static String valueOf(Object obj) {    return (obj == null) ? "null" : obj.toString();}
String -> int
s="12345";int i;//第一种方法i=Integer.parseInt(s);//Integer.parseInt()就是专为String转int所设计的并且有不同重载版本,可以设定进制://源码public static int parseInt(String s, int radix){......}public static int parseInt(String s) throws NumberFormatException {    return parseInt(s,10);}//第二种方法i=Integer.valueOf(s).intValue();//源码public static Integer valueOf(String s) throws NumberFormatException {    return Integer.valueOf(parseInt(s, 10));}//parseInt返回的是int值,之后就是调用Integer.valueOf(int)//Integer.intVaule就是获取Integer中所封装的int值了。
3.优化功能(对象池)
其实这个特点应当算是虚拟机的特点,但是如果不是对象的话虚拟机也无法实现这样的优化功能,这里用到的就是一个对象池的概念,在python中同样存在,另外啰嗦一句,与python相比Java的基本类型还不是对象(不继承自Object)而python中所有的对象都继承自Object。
//例子:Integer i = 3;//这句代码经过编译之后被编译器优化为:Integer localInteger = Integer.valueOf(3);

可以看出装箱就是使用的valueOf,拆箱就是使用的intValue,(这里只是一Integer为例),这些都是编译器的任务。而真正执行Integer.valueOf(3)的时候是运行期了,看一下源码:
public static Integer valueOf(int i) {    if (i >= IntegerCache.low && i <= IntegerCache.high)        return IntegerCache.cache[i + (-IntegerCache.low)];    return new Integer(i);}
使用到了IntegerCache,而这个IntergerCache就是所谓的Integer的对象池。IntegerCache是Integer中的一个static的内部类,在JVM第一次载入Integer类的时候,就会加载IntegerCache类,而IntegerCache中使用static块进行初始化。所以第一次加载Integer类的时候就已经初始化好了IntegerCache类了。这一点是与python不同的python的小整数池一直都是在虚拟机内部的。

看源码:

public final class Integer extends Number implements Comparable<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) {                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() {}}.........}

从源码中可以看出,IntegerCache中所存储的是-128~127的Integer对象。另外注意IntegerCache中private构造函数。

本文仅以Integer类做为Java包装类学习的示例,基本思想相似,但是各个类都有区别,因为所处理的对象不同。


0 0
原创粉丝点击