Java基本数据类型的大小,他们的封装类以及自动拆箱和装箱

时间:2022-12-20 15:47:53

Java提供了一套基本数据类型,总共有八种,也会有人说是有九种。

在我们的印象中,很多人可能会说出byte,short,int,long,float,double,boolean,char这八种数据类型。

那么还有一种是哪种呢,它到底是不是数据类型呢?

我们很容易忽略一个void,有人说void也是数据类型之一,也有人说不是。

在Java的API中,并未说明void是基本数据类型,那为什么Java圣经“Think in Java”还有一些书籍会说void是一种基本数据类型呢?

众所周知,Java的数据类型分两种,一种是基本数据类型,一种是引用类型。两者的本质区别是:基本类型是在堆栈处分配空间存“值”,但是引用类型,是在堆里面分配空间存“值”。Void是不能new出来的,也就是不能在堆里面分配空间存值,那就是一开始就在堆栈处分配好空间了。所以,将void归于基本数据类型,也有道理。

所以加上前面八种数据类型,java总共为我们提供了九种数据类型。

下面我引用了rabbit_in_android文章中的一个表格来介绍一下九种数据结构的大小,默认值和封装类。

基本类型 大小(字节) 默认值 封装类
byte 1 (byte)0 Byte
short 2 (short)0 Short
int 4 0 Integer
long 8 0L Long
float 4 0.0f Float
double 8 0.0d Double
boolean - false Boolean
char 2 \u0000(null) Character
void - - Void










那么为什么Java又会有基本类型的封装类呢,为什么要这样做?

用基本数据类型的好处是:在java中使用基本类型来存储语言支持的基本数据类型,这里没有采用对象,而是使用了传统的面向过程语言所采用的基本类型,主要是从性能方面来考虑的:因为即使最简单的数学计算,使用对象来处理也会引起一些开销,而这些开销对于数学计算本来是毫无必要的。

封装类:在java中,泛型类包括预定义的集合,使用的参数都是对象类型,无法直接使用这些基本数据类型,所以java又提供了这些基本类型的包装器。如List<Integer>是一个整形的List集合,不能这样子写List<int>。


自动装箱:当我们创建一个Integer对象的时候,可以这样

Integer i = 100;
//注意,不是i = 100
实际上,执行上面那句代码的时候,jvm自动为我们执行了:

Integer i = Integer.valueOf(100);
这就是将基本数据类型装箱成为它们的封装类类型。


自动拆箱:就是将对象中的基本数据从对象中自动取出,如下:

Integer i = 100;     //自动装箱
int x = i;      //自动拆箱
实际上,拆箱操作就是自动执行了int x = i.intValue();

基本数据类型和封装类的一些区别:
  • 1.基本数据类型只能按值传递,而封装类按引用传递。
  • 2.基本类型在堆栈中创建;而对象类型在堆中创建,对象的引用在堆栈中创建。基本类型由于在堆栈中,效率会比较高,但是可能会存在内存泄漏的问题。
  • 3.int类型的默认值是0,而Integer的默认值是null。

附加上一些知识点:
//在-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));
输出的结果是:
  i1==i2: false
  i3==i4: true
说明:“==”是用来比较两个对象的引用(内存地址)是否相同,也用来比较两个基本数据类型的变量值是否相等。
int 的自动装箱,是系统执行了 Integer.valueOf(int i),来看看valueOf方法源码:
public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)  // 没有设置的话,IngegerCache.high 默认是127
        return IntegerCache.cache[i + 128];      //返回的是缓存的Integer对象
    else
        return new Integer(i);
}
对于-128到127(默认是127)之间的值,Integer.valueOf(int i)返回的是缓存的Integer对象(并不是新创建一个对象)。
而范围外的其它值,执行Integer.valueOf(int i)返回的是一个新创建的Integer对象。
所以对于上面例子的 i1 和 i2 ,它们是新创建的Integer对象,所以会返回false,而 i3 和 i4 是指向同一个缓存的Integer对象,所以返回true。

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

Integer i3 =new Integer(100); 
Integer i4 =new Integer(100); 
System.out.println("i3==i4: "+(i3==i4));//显示false

参考:

http://write.blog.csdn.net/postedit

http://blog.csdn.net/rabbit_in_android/article/details/49793813

http://blog.csdn.net/syc434432458/article/details/49964089