java核心基础 --- 基础数据类型

本篇博文主要介绍 java 基础数据类型、基本类型的数据转换、自动装箱拆箱机制。

1. 基础数据类型

  1. 整型

    • 整型包含 byte(1字节)、short(2字节)、int(4字节)、long(8字节)

    • 需要注意的是,如果直接将一个较小的数赋值给 byte 或者是 short 的话,系统会自动把该数值当成 byte 或者 short 类型处理:

      byte a = 56
      
    • 当使用 long 类型时,需要在后面加上一个 L,如果没有的话,仍然当成 int 类型。例如,下面的代码就会报出编译错误:

      long bigValue = 999999999999
      
    • JDK7 新增了对二进制整数的支持,二进制的整数以 0b 或者 0B 开头,如:

      int binVal = 0b10000000000000000000000000000011
      

      需要注意的是,所有数字在计算机底层都是以二进制形式存在的,并且是以补码的形式保存所有整数。当我们要计算一个二进制整数的值时,需要将补码转换为原码。他们之间的关系是:正数的原码和补码完全相同,负数的补码是其反码加 1;反码是对原码按位取反,只是最高位(符号位)保持不变。例如,上述数值表示补码,其反码为 10000000000000000000000000000010 ,其原码为反码取反 (符号位不变)11111111111111111111111111111110 ,为 -2147483645。

  2. 浮点型

    • double(8字节)
    • float(4字节),如果需要使用 float 时需要在后面添加一个 F 或者 f。由于系统默认把一个浮点型归为 double 类型,因此如果不加 F 或者 f 的话,会产生编译错误。
  3. 字符型

    • char,2字节,可以表示中文
  4. 布尔型

    • boolean,1字节

2. 基本类型的类型转换

2.1 自动转换

基本类型表示范围小的数可以向基本类型表示范围大的数进行自动类型转换:

byte --> char、short --> int --> long --> float --> double

2.2 强制转换

强制类型转换时容易出现溢出的情况,例如:

int iValue = 233;
byte bValue = (byte)iValue;
System.out.println(bValue);    // 结果为 -23

在上述例子中,iValue 用二进制表示为 00000000000000000000000011101001。当强制转换成 byte 类型时,只能取后八位,即 11101001,二进制数是补码,我们把它转换为反码为 11101000,转换为原码为 10010111,此数值表示 -23。

2.3 表达式类型的自动提升

// 下面的代码会出现编译错误
short sValue = 5;
sValue = sValue - 2;

3. 自动装箱拆箱

自动装箱就是将基本数据类型转换为包装类型;拆箱就是把包装类型转换为基本数据类型,以 Integer 类型为例:

public class Test{
    public static void main(String[] args){
        Integer i = 20;
        int n = i;
    }
}

通过反编译 class 文件之后得到如下内容:

java核心基础 --- 基础数据类型

可以看出,在自动装箱的过程中,调用的是 Integer.valueOf 方法,而在自动拆箱的过程中调用的 Integer.intValue 方法。 其他的包装类也是类似。有了上面的基础,我们来看看这段代码的运行结果:

public class PackAndUnbox {
	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);
	}
}

有上面所说的知识点可以知道,这四个变量的定义都会自动装箱,即调用 Integer.valueOf 方法。那我们现在来看一下 Integer.valueOf 方法的源码:

 public static Integer valueOf(String s) {
     return Integer.valueOf(parseInt(s, 10));
 }

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

从源码可知,自动装箱时,当数值在 [low,high] 之间时(通过查看源码此范围为 -128,127),该数值可以直接由 IntegerCache.cache 数组生成,而且该数组由 static final 修饰,因此返回的对象应该是相等的。由此可以得出,上面程序的运行结果如下:

true;
false;

当其他包装类自动装箱时,如果要判断两个对象是否相等,判断的依据也是各个包装类的 valueOf 方法,这里就不再继续展开,详细的大家可以自行去查看源码或者查阅网上的博客,就比如这 一篇