JAVA-基础知识-基础数据类型,常量池

JAVA-基础知识-基础数据类型,常量池

基础类型有这样一张表就差不多了

类型 包装类 默认值 最大值 最小值 长度 描述
byte Byte 0 127(2^7-1) -128(-2^7) 8 有符号的,以二进制补码表示的整数
boolean Boolean false 1 boolean只有两个取值:true 和 false
short Short 0 32767(2^15-1) -32768(-2^15) 16 有符号的以二进制补码表示的整数
char Character ‘\u0000’ ‘\uffff’ ‘\u0000’ 16 char类型是一个单一的 16 位 Unicode 字符
int Integer 0 2,147,483,647(2^31-1) -2,147,483,648(-2^31) 32 有符号的以二进制补码表示的整数
long Long 0L 9,223,372,036,854,775,807(2^63-1) -9,223,372,036,854,775,808(-2^63) 64 有符号的以二进制补码表示的整数
float Float 0.0f 32 单精度、符合IEEE 754标准的浮点数,不能用来表示精确的值,如货币
double Double 0.0d 64 双精度、符合IEEE 754标准的浮点数,不能表示精确的值,如货币

自动拆箱和装箱
Java 5增加了自动装箱与自动拆箱机制,方便基本类型与包装类型的相互转换操作。

//在Java 5之前,只能这样做
Integer value = new Integer(10);
//或者这样做
Integer value = Integer.valueOf(10);
//直接赋值是错误的而java5开始,直接赋值是合法的,由编译器来完成转换
Integer value = 10;

实现:
由编译器自动添加转换方法

  • 静态方法valueOf(基本类型):将给定的基本类型转换成对应的包装类型;
  • 实例方法xxxValue():将具体的包装类型对象转换成基本类型;

有个坑,不知道你以前有没有注意到

/*Integer的构造方法,接受一个整型参数,Integer对象表示的int值,保存在value中*/ 
public Integer(int value) {
    this.value = value;
}
/*equals()方法判断的是:所代表的int型的值是否相等*/ 
public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        eturn value == ((Integer)obj).intValue();
    }
    return false;
}
/*返回这个Integer对象代表的int值,也就是保存在value中的值*/
public int intValue() {
    return value;
}
/** 
 * 首先会判断i是否在[IntegerCache.low,Integer.high]之间 
 * 如果是,直接返回Integer.cache中相应的元素 
 * 否则,调用构造方法,创建一个新的Integer对象 
 */
public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
}
/** 
 * 静态内部类,缓存了从[low,high]对应的Integer对象 
 * low -128这个值不会被改变 
 * high 默认是127,可以改变,最大不超过:Integer.MAX_VALUE - (-low) -1 
 * cache 保存从[low,high]对象的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) {
                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);
            }
            high = h;
            ache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
    }
    private IntegerCache() {}
}        

在Integer的源码里面有这样一段,通过分析

  1. Integer有一个实例域value,它保存了这个Integer所代表的int型的值,且它是final的,也就是说这个Integer对象一经构造完成,它所代表的值就不能再被改变。
  2. Integer重写了equals()方法,它通过比较两个Integer对象的value,来判断是否相等。
  3. 重点是静态内部类IntegerCache,通过类名就可以发现:它是用来缓存数据的。它有一个数组,里面保存的是连续的Integer对象。
    • low:代表缓存数据中最小的值,固定是-128。
    • high:代表缓存数据中最大的值,它可以被该改变,默认是127。high最小是127,最大是Integer.MAXVALUE-(-low)-1,如果high超过了这个值,那么cache[ ]的长度就超过Integer.MAXVALUE了,也就溢出了。
    • cache[]:里面保存着从[low,high]所对应的Integer对象,长度是high-low+1(因为有元素0,所以要加1)。
  4. 调用valueOf(int i)方法时,首先判断i是否在[low,high]之间,如果是,则复用Integer.cache[i-low]。比如,如果Integer.valueOf(3),直接返回Integer.cache[131];如果i不在这个范围,则调用构造方法,构造出一个新的Integer对象。
  5. 调用intValue(),直接返回value的值。通过3和4可以发现,默认情况下,在使用自动装箱时,VM会复用[-128,127]之间的Integer对象。

然后可以试试这个:

public static void main(String[] args) {
  //基本数据类型的常量池是-128到127之间。
  // 在这个范围中的基本数据类的包装类可以自动拆箱,比较时直接比较数值大小。
  
  //int的自动拆箱和装箱只在-128到127范围中进行,超过该范围的两个integer的 == 判断是会返回false的。
      
  Integer a1 = 128;
  Integer a2 = 128;
  Integer a3 = -128;
  Integer a4 = -128;
  System.out.println(a1 == a2); //false
  System.out.println(a3 == a4); //true
  
  Byte b1 = 127;
  Byte b2 = 127;
  Byte b3 = -128;
  Byte b4 = -128;
  //byte都是相等的,因为范围就在-128到127之间
  System.out.println(b1 == b2); //true
  System.out.println(b3 == b4); //true
  
  Long c1 = 128L;
  Long c2 = 128L;
  Long c3 = -128L;
  Long c4 = -128L;
  System.out.println(c1 == c2); //false
  System.out.println(c3 == c4); //true
  
  //char没有负值
  //发现char也是在0到127之间自动拆箱
  Character d1 = 128;
  Character d2 = 128;
  Character d3 = 127;
  Character d4 = 127;
  System.out.println(d1 == d2); //false
  System.out.println(d3 == d4); //true
 }
  1. Integer默认复用了[-128,127]这些对象,其中高位置可以修改;
  2. Byte复用了全部256个对象[-128,127];
  3. Short服用了[-128,127]这些对象;
  4. Long服用了[-128,127];
  5. Character复用了[0,127],Charater不能表示负数;
  6. Double和Float是连续不可数的,所以没法复用对象,也就不存在自动装箱复用陷阱。
  7. Boolean没有自动装箱与拆箱,它也复用了Boolean.TRUE和Boolean.FALSE,通过Boolean.valueOf(boolean b)返回的Blooean对象要么是TRUE,要么是FALSE,这点也要注意。

你可能感兴趣的:(java基础)