其他网址
JAVA中Long与Integer比较容易犯的错误(比较数据equals)_java_我主要负责转载优秀的技术博文-CSDN博客
另见:《Java开发实战经典》=> 6.12 包装类
简介
问题起源:Long或Integer如何比较大小呢?
- 错误方法:
直接使用==来比较。 因为Long与Ineger都是包装类型,是对象。 而不是普通类型long与int
使用equals方法。因为equals方法只能比较同类型的类,例如两个都要是Integer类型。- 正确方法:用,或者先使用longValue()或intValue()方法来得到他们的基本类型的值然后使用==比较也是可以的。
拆箱与装箱原理
装箱就是将基本数据类型转化为包装类型,那么拆箱就是将包装类型转化为基本数据类型。
package org.example.a; public class Demo{ public static void main(String[] args) { //自动装箱,底层其实执行了Integer a=Integer.valueOf(1); Integer a = 10; //自动拆箱,底层其实执行了int b=a.intValue(); int b = a; } }
查看反汇编文件
依次执行如下命令
javac -d . org\example\a\Demo.java
javap -c org.example.a.Demo
输出结果如下:
E:\work\idea_proj\test_java\src>javap -c org.example.a.Demo
Compiled from "Demo.java"
public class org.example.a.Demo {
public org.example.a.Demo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: returnpublic static void main(java.lang.String[]);
Code:
0: bipush 10
2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
6: aload_1
7: invokevirtual #3 // Method java/lang/Integer.intValue:()I
10: istore_2
11: return
}
Integer a = 10;
执行上面那句代码的时候,系统为我们执行了:Integer a = Integer.valueOf(10);int b = a;
执行上面那句代码的时候,系统为我们执行了:int b = a.intValue();
缓存问题
分析过程
其他网址
测试代码
package org.example.a;
public class Demo{
public static void main(String[] args) {
Integer a = 100;
Integer b = 100;
Integer c = 200;
Integer d = 200;
System.out.println(a == b);
System.out.println(c == d);
}
}
执行结果
true
false
原因:
Integer有个缓存,原理如下。
valueOf源码
//private static class IntegerCache { // static final int low = -128; // static final int high = 127; public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
当i的值位于[-128,127]的时候,会直接返回Integer缓存数组中相应对象的引用,如果i大于127或小于-128,会重新创建一个Integer实例,并返回。
那么第一条式子a和b的值都在缓存范围内,因此他们指向同一个对象,因此返回true。c和d的值不在范围内,都是通过new创建出来的,因此不是同一个对象,返回false。
其他包装类的缓存
Byte、Short、Integer、Long、Character的valueOf()实现机制类似。
包装类 | 说明 |
Byte | 相同值的Byte比较永远返回true。因为byte取值范围就是[-128,127]。 |
Short、Integer、Long | 相同值在[-128,127]则返回true,不在则返回false |
Character | 要返回true,只需保证i <= 127。因为char最小值为0,本来就大于等于-128。 |
Float、Double | 永远返回false。因为其永远返回新创建的对象,因为一个范围内的整数是有限的,但是小数却是无限的,无法保存在缓存中。 |
Boolean | 只有两个对象,要么是true的Boolean,要么是false的Boolean,只要boolean的值相同,Boolean就相等。 |