以前一直忽略的知识现在补上
public class MainTest {
public static void main(String args[]) {
Integer integer_one = 3;
Integer integer_two = 3;
Integer integer_three = 129;
Integer integer_four = 129;
Integer intger_five = new Integer(3);
int int_one = 3;
boolean reult1 = integer_one == integer_two;
boolean reult2 = integer_one == int_one;
boolean result3 = integer_three == integer_four;
boolean result4 = int_one == intger_five;
System.out.println(reult1);
System.out.println(reult2);
System.out.println(result3);
System.out.println(result4);
}
}
输出:
true
true
false
true
以前一直不理解 却忘记了补充 ,永远要对知识充满一个敬畏之心
首先要理解 输出结果必须要懂的从字节码层面去看:
将上面的代码反编译后:
如果看不懂字节码 的话,总可以看到字节码的注释部分吧?
这里直接来说明字节码层面体现的问题
当Integer
直接赋予一个数字时,将调用valueOf方法进行返回。
比如如下代码:
Integer integer_one = 3;//它等价于 Integer integer_one = Integer.valueOf(3);
我们来看看valueOf
做了哪些手脚
//Integer.java
public static Integer valueOf(int i) {
//IntegerCache.low==-128
//IntegerCache.high ==127 大家不信的话可以待会可以看看下文分析
//当传入的数据在一个字节范围内(-128到127) 时,返回缓存区的引用
if (i >= IntegerCache.low && i <= IntegerCache.high)
//IntegerCache为内部类 cache为一个Integer数组
return IntegerCache.cache[i + (-IntegerCache.low)];
//如果不在一字节范围内重新创建
//所以不管如何 Integer =3 将是一个new对象的引用
return new Integer(i);
}
如果想控制缓存请使用虚拟机参数:-XX:AutoBoxCacheMax=<size>
//Integer.java
//这个类为Integer内部类
private static class IntegerCache {
/***
已删除无关紧要代码
***/
static final int low = -128;
static final int high;
static final Integer cache[];
static {
/***
已删除无关紧要代码
***/
int h = 127;
high = h;
cache = new Integer[(high - low) + 1];
}
private IntegerCache() {}
}
所以得出一个结论:
当默认不改变虚拟机缓存设置。那么Integer直接赋予一个小于一字节的直接数值时,将返回事先已经有的Integer对象。
故:
Integer integer_one = 3;
nteger integer_two = 3;
比较时将相等,因为两者都小于一个字节范围 ,所以两者指向同一缓存对象
Integer integer_three = 129;
Integer integer_four = 129;
比较时将相等,因为两者都大于一个字节范围 ,所以两者创建时都用了new Integer方法。而==号在java中时比较两个对象引用是否为同一地址。故两者比较时返回不相等
大家在看上图字节码图片的时候,是不是看到intValue方法被调用?不记得看不懂没关系,请继续看下文。
当一个Integer对象和一个int基本类型比较时,虚拟机首先会调用Integer的 intValue方法返回一个int数值进行比较
对应方法如下:
//Integer.java
public Integer(int value) {
this.value = value;
}
举例说明:
int int_one = 3;
Integer intger_five = new Integer(3);
Integer integer_one = 3;
//以下代码等价于
//boolean result4 = int_one== intger_five.intValue()//返回int类型的数值因为和int_one数值相等所以为true
boolean result4 = int_one == intger_five;
//同上
boolean reult2 = integer_one == int_one;
关于Integer
的equals
方法比较简单 不在做详细举例说明了
请先看equals方法
//Integer.java
//如果传入的是int类型那么启用自动装箱机制 变为Integer类型
public boolean equals(Object obj) {
//如果是Integer类型那么直接比较他们的int数值大小即可
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}