java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。
Java 语言是一个面向对象的语言,但是 Java 中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,所以在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类,有些地方也翻译为外覆类或数据类型类。
前言
大家都知道在 Java 中,除了 8 种基本数据类型外,其他的都是引用类型。使用引用类型是为了更好地贯彻面向对象的思想,那为什么还要保留 8 种基本数据类型呢?
这其实更多地是照顾程序员的习惯。为了既照顾程序员的习惯,同时又能全面贯彻面向对象编程的思想,Java 中引入了包装类机制。
所谓的包装类就是为 8 种基本数据类型分别定义了相应的引用类型,其对应关系如下:
显然,除了 int 及 char 外,其余的包装类都是将对应的基本数据类型的首字母大写即可。 那为什么要引入包装类呢?前面已经说过,是为了全面贯彻面向对象的编程思想,具体地说就是非引用类型的数据在使用时会有许多制约,比如
对于引用类型,可直接使用 list.add(obj); 进行添加,但是对于基本数据类型则无法添加,从而不能使用 ArrayList 中的许多方法(如排序、删除等),显然会造成许多不便,而使用包装类则可以很好地避免这种缺陷。
- List list=new ArrayList();
同时,从 JDK 1.5 开始提供了自动装箱和自动拆箱的功能,因而目前可以有以下 3 种初始化包装类的方法:
方法 1:直接传入相应的基本数据类型变量或常量,如
- int a1=3;Integer a2=new Integer(a1);
- Float f=new Float(3.14f);
- Boolean b=new Boolean(true);
方法 2:通过传入字符串,如
- Integer a = new Integer("3");
- Float f = new Float("3.14");
- Boolean b = new Boolean("true");
值得注意的是使用 "True" 也可以,如
- Boolean b=new Boolean("True");
方法 3:通过自动装箱功能,如
值得注意的是可使用
- Integer a=3;Float f=3.14f;Boolean b=true;
和
- new Float("3.14")
这样的语句来初始化 Float 类型变量,但是却不能使用 Float f=3.14; 来初始化 Float 类型变量,因为 3.14 是 double 类型,它只能被自动装箱为 Double 类型变量。
- new Float("3.14f")
我们知道,引用类型使用 == 进行比较时,只有当二者指向同一个对象时,才会返回 true,否则即使值相等也返回 false. 包装类也属于引用类型,所以以下代码的执行结果为 false,
- Float f1 = new Float(3.14f);
- Float f2 = new Float(3.14f);
- System.out.println(f1 == f2);
但是,下面一段代码的输出结果却和前面讨论的不一样,这是为什么呢?
- import java.util.*;
- public class TestWrapperClass
- {
- public static void main(String[]args)
- {
- Integer t1=3;
- Integer t2=3;
- System.out.println(t1==t2);
- Integer t3=128;
- Integer t4=128;
- System.out.println(t3==t4);
- Boolean b1=true;
- Boolean b2=true;
- System.out.println(b1==b2);
- }
- }
其输出结果如下图所示:
如果按照前面的讨论,应该都输出 false 才对,但这里 t1 与 t2,b1 与 b2 的比较结果却为 true. 这不科学啊!
原来,Java 为了获得更高的执行效率,在某些类的设计中引入了缓存机制!
此处的 Integer 及 Boolean 类的设计即是如此。java.lang.Integer 类的部分源代码如下所示:
- static final Integer[]cache=new Integer[-(-128)+127+1];
- static{
- for(int i=0;i<cache.length;i++)
- cache[i]=new Integer[i-128);
- }
显然,系统把 - 128~127 之间的整数装箱成 Integer 实例,并通过 cache 数组进行缓存,所以只要是 - 128~127 之间的 Integer 类型变量,其指向的对象都是 cache 数组成员,从而只要有两个值相同且在 - 128~127 之间的 Integer 变量,它们指向的对象就是同一个,故采用 == 进行比较时也返回 true.Boolean 的情形与之类似。
实际上,不只是在 Java 中,在 Android 中的一些类也采用了缓存机制,如 Android 中的 ListView 就是一个典型的例子,在继承的方法 getView 中,convertView 其实就是采用了缓存机制,从而大大节省了系统资源开支,加快了图形渲染的速度。此处暂且不表,在后面还会再提到。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言留言交流。
来源: http://www.phperz.com/article/17/1221/358626.html