基本数据类型与其包装类型
---- 基本类型 与 包装类型
Java 中预定义了八种基本数据类型,包括:byte,int,long,double,float,boolean,char,short。基本类型与对象类型最大的不同点在于,基本类型基于数值,对象类型基于引用。
基本类型的变量在栈的局部变量表中直接存储的具体数值,而对象类型的变量则存储的堆中引用。显然,相对于基本类型的变量来说,对象类型的变量需要占用更多的内存空间。
---- 笔试结合
在jdk1.5以后,开始引入自动装箱和拆箱的操作,例如:
public static void main(String[] args){
int age = 21;
Integer integer = age; //自动装箱 相当于 Integer integer = new Integer(age);
int num = integer; //自动拆箱 相当于 int num = integer.intValue();
}
当然,拆装箱是需要方法调用的,也就是需要栈帧的入栈出栈的,直白点说,就是耗资源,所以我们的程序中应当尽量避免大量的「拆装箱」操作。
举个栗子:
public static void main(String[] args){ Integer i1 = 100; Integer i2 = 100; Integer i3 = 200; Integer i4 = 200; System.out.println(i1==i2); System.out.println(i3==i4); }
结果:
true false
分析:
这里就要引入Integer类的 valueOf方法使用到一个叫 IntegerCache 的缓存区,它能够默认缓存[-128,127] 之间的 Integer 实例,所以,当100在其缓存区范围内,会从中返回相应的值给i1,同理,i2也是从这里拿取的,所以他们两个指向的是同一个地方,所以结果为 true,但是假如 i2的定义如下的话,那么结果的比较就是为false了,因为 此时的 i1 和 i2并不在同个地方,i1变量在栈中,而 i2 是在堆里,位置不同
Integer i2 = new Integer(100);
而第二个输出「false」也是很好理解的,因为 200 不再缓存池缓存的范围内,所以每次调用 valueOf 方法都会新建一个不同的 Integer 实例。
举个栗子
public static void main(String[] args){ Double i1 = 100.0; Double i2 = 100.0; Double i3 = 200.0; Double i4 = 200.0; System.out.println(i1==i2); System.out.println(i3==i4); }
结果:
false false
分析:
因为在 Double 和 Float 中,没有存在有缓存区这个东西,这是因为就算给定任意一个区间,都无法确定这个区间里面有多个double类型或者float类型的值。所以,它每一个 double 型数值包装一个新的 Double 实例,如下:
public static Double valueOf(double d) { return new Double(d); }
举个栗子
public class Test8 { public static void main(String[] args) { Integer i = 10; Integer a3 = 10; Float a = 10f; Double c = 10.0; int b = 10; float d = 10f; System.out.println(i == d); System.out.println(b == d); System.out.println(c == b); System.out.println(a.equals(d)); System.out.println(c.equals(i)); } }
结果:
true true true true false
分析:
这里要需要了解一下在java中 “==” 和 equals()方法,“==”如果比较的两者是基本数值的话,那么比较的就是他们的值,而如果两个都是对象变量的话,那么比较的是他们的地址,而“equals()”方法,比较的是变量的值以及返回参数类型,所以,虽然变量a,c,b,d的数值类型不同,但是其本身的值都是相等,比较结果为true。
所以,Integer 类型对象 和 Double 类型对象 比较,虽然数值是相同的,但是两者是不一样的类型,所以为false。如下:
参考文章: 基本数据类型及包装类