下面这个例子,想必有人踩过这个坑。
Integer a = 127;
Integer b = 127;
//输出true
System.out.println(a == b);
而修改下a、b的值后,
Integer a = 128;
Integer b = 128;
//输出false
System.out.println(a == b);
Java 的包装类
这究竟是为什么?Integer 是 基本数据类型 int 的包装类型。基本类型和包装类型对应关系。
基本数据类型 | 包装类型 |
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
这里要说到 Java 的 Integer 常量池,常量池维持着:-128~127 数据范围的数据,在这范围内的数字,则直接进行比较,不在这范围内的,则是 Java 对象的比较,对象比较的引用地址;所以会出现开头运行出现的结果。
jdk 常量池源代码,如下:
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;//最大值
//此次省略代码。。。
private IntegerCache() {}
}
采用缓存的设计,也是基于运行效率的考量。
比较的两种正确写法
第一种写法:直接转换成 基本数据类型进行比较
Integer a = 128;
Integer b = 128;
//输出 true
System.out.println(a.intValue() == b.intValue());
可以看到 jdk 源代码里面 intValue()方法直接返回一个 int 类型数据。
public int intValue() {
return value;
}
第二种写法:使用 equals 方法
Integer a = 128;
Integer b = 128;
//输出 true
System.out.println(a.equals(b));
可以看到 jdk 源代码里面 equals(Object obj) 方法最后也是使用 int 类型数据来判断的。
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}