java基础面试题-new Integer, Integer.valueOf区别

知识要点

  • java基本数据类型
  • 拆箱装箱
  • 缓冲池的使用
  • 缓冲池默认范围

面试中,有时候会问到类似new Integer(100) Integer.valueOf(100)的区别?
一般来说,对象都是在堆里创建的,所以所有对象的地址都不同,但真的是这样的吗?

这个问题,其实反应了你对java包装类型的源码了解多少,有没有真正的看过包装类型的源码。
要理解这个问题,我们首先要知道java的基本数据类型有哪些?

java基本数据类型

基本类型 包装类型 占用空间
boolean Boolean 1字节
byte Byte 2字节
char Character 2字节
short Short 2字节
int Integer 4字节
float Float 4字节
long Long 8字节
double Double 8字节

boolean 只有两个值:true、false,可以使用 1 bit 来存储,但是具体大小没有明确规定。JVM 会在编译时期将 boolean 类型的数据转换为 int,使用 1 来表示 true,0 表示 false。JVM 支持 boolean 数组,但是是通过读写 byte 数组来实现的。

字符串的数据解析成对应的数据类型

   int x =Integer.parseInt("9");
   double c = Double.parseDouble("5");
   int b = Integer.parseInt("444",16);
   可具体参考包装类型的api

基本类型转化成string,可以直接+"",也可以转换成包装类型,使用包装类型的api来转换成string类型。

String test = 1 + "";
Integer value = Integer.valueOf("123");
String str = value.toString();
可具体参考包装类型的api

拆箱装箱

基本类型都有对应的包装类型,基本类型与其对应的包装类型之间的赋值使用自动装箱与拆箱完成。

Integer x = 10;     // 装箱
int y = x;         // 拆箱

缓冲池的使用

java针对一定数据范围的数据,使用valueOf的方法,会重复使用缓冲池里的数据,不会返回新的对象,既然某个数据范围使用非常多,为什么要频繁创建和销毁对象呢,这是jvm层的一个自动优化。

new Integer(100) 与 Integer.valueOf(100) 的区别在于:

  • new Integer(100) 每次都会新建一个对象;
  • Integer.valueOf(100) 会使用缓存池中的对象,多次调用会取得同一个对象的引用。
Integer x = new Integer(100);
Integer y = new Integer(100);
System.out.println(x == y);    // false
Integer z = Integer.valueOf(100);
Integer k = Integer.valueOf(100);
System.out.println(z == k);   // true

valueOf() 方法的实现比较简单,就是先判断值是否在缓存池中,如果在的话就直接返回缓存池的内>容。

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

在 Java 8 中,Integer 缓存池的大小默认为 -128~127。缓冲池的下界是 - 128,不可改变,可以通过属性"java.lang.Integer.IntegerCache.high"设置缓存池的最大值。

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) {
        try {
            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);
        } catch( NumberFormatException nfe) {
            // If the property cannot be parsed into an int, ignore it.
        }
    }
    high = h;

    cache = new Integer[(high - low) + 1];
    int j = low;
    for(int k = 0; k < cache.length; k++)
        cache[k] = new Integer(j++);

    // range [-128, 127] must be interned (JLS7 5.1.7)
    assert IntegerCache.high >= 127;
}

缓冲池默认范围

包装类型 缓冲池
Boolean true 或false
Byte 所有字节
Short -128-127
Integer -128-127
Character \u0000 to \u007F

你可能感兴趣的:(理解java,Java面试宝典收集录)