文章标题:
Java SDK源码中Integer的源码剖析系列起始篇
文章内容:
目录
- 1. 应用场景
- 2. 原理探究
- 2.1. 构造机制
- 2.2. valueOf方法
- 2.2.1. 处于-128到127范围时从缓存获取
- 2.2.2. 解读Integer.valueOf(1)==Integer.valueOf(1)
- 2.2.3. 解读(Integer val1 = 1) == (Integer val2 = 1)
- 2.2.4. 解读(Integer val1 = 128) != (Integer val2 = 128)
1. 应用场景
在Java代码中,我们经常会用到Integer类型来处理整数相关操作。下面通过一个示例类来展示不同方式创建Integer对象时的引用比较情况:
public class IntegerUsageDemo
{
public static void main(String[] args)
{
// 通过new关键字创建的两个Integer对象,引用不同
Integer num1 = new Integer(1);
Integer num2 = new Integer(1);
System.out.println(num1 == num2); // 输出false
// 直接赋值方式创建的Integer对象,引用相同
Integer num3 = 1;
Integer num4 = 1;
System.out.println(num3 == num4); // 输出true
// 使用valueOf方法创建的Integer对象,引用相同
Integer num5 = Integer.valueOf(1);
Integer num6 = Integer.valueOf(1);
System.out.println(num5 == num6); // 输出true
System.out.println(num3 == num5); // 输出true
}
}
2. 原理探究
2.1. 构造机制
// final修饰表示Integer类不可被继承,实现Comparable<Integer>接口以支持比较操作
public final class Integer extends Number implements Comparable<Integer> {
private final int value; // 底层使用int类型存储数值,且被final修饰
public Integer(int value) {
this.value = value; // 简单的属性赋值操作
}
}
Integer类具有不可变性,具体体现在以下几点:
* 类被final修饰,无法被继承扩展。
* 内部存储数值的属性value被final修饰,一旦赋值不可更改。
* 没有提供任何对外修改value属性的方法。
2.2. valueOf方法
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
}
public static Integer valueOf(int i) {
// 当数值在-128到127范围内时,直接从缓存中获取对应对象
if (i >= IntegerCache.low && i <= IntegerCache.high) {
return IntegerCache.cache[i + (-IntegerCache.low)];
}
// 超出范围则创建新的Integer对象
return new Integer(i);
}
2.2.1. 处于-128到127范围时从缓存获取
这里涉及到IntegerCache类,其内部实现如下:
private static class IntegerCache {
static final int low = -128; // 缓存的最小数值
static final int high; // 缓存的最大数值,需要动态计算
static final Integer cache[]; // 用于存储缓存的Integer对象数组
static {
// 默认最大缓存数值为127
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = Integer.parseInt(integerCacheHighPropValue);
h = Math.max(i, 127);
// 确保不超过Integer能表示的最大范围
h = Math.min(h, Integer.MAX_VALUE - (-low) - 1);
} catch (NumberFormatException nfe) {
// 解析属性失败时忽略,使用默认值
}
}
high = h;
// 初始化缓存数组,将low到high范围内的数值都存入缓存
cache = new Integer[(high - low) + 1];
int j = low;
for (int k = 0; k < cache.length; k++) {
cache[k] = new Integer(j++);
}
assert IntegerCache.high >= 127; // 断言最大缓存值不小于127
}
private IntegerCache() {} // 私有构造方法,防止实例化
}
2.2.2. 解读Integer.valueOf(1)==Integer.valueOf(1)
当执行Integer.valueOf(1)
时,由于1处于-128到127的缓存范围内,会直接从IntegerCache的缓存数组中获取已存在的对象,所以两次调用Integer.valueOf(1)
返回的是同一个对象,因此Integer.valueOf(1) == Integer.valueOf(1)
的结果为true。
2.2.3. 解读(Integer val1 = 1) == (Integer val2 = 1)
在Java中,直接将基本类型int赋值给Integer类型时,实际上会自动调用Integer.valueOf
方法。所以Integer val3 = 1;
等同于Integer val3 = Integer.valueOf(1);
,同理Integer val4 = 1;
也是如此,因此val3和val4引用的是同一个缓存对象,所以val3 == val4
的结果为true。
2.2.4. 解读(Integer val1 = 128) != (Integer val2 = 128)
由于IntegerCache只缓存了-128到127范围内的Integer对象,128超出了这个范围,所以每次调用Integer.valueOf(128)
都会创建一个新的Integer对象,因此val1和val2是两个不同的对象,它们的引用不同,所以val1 != val2
的结果为false。
相关文章
暂无评论...