本文共 2827 字,大约阅读时间需要 9 分钟。
目录
1. 比较原理
-
== 比较的是内存地址
-
equals比较的是值
首先我们来了解一下JVM内存区结构:
java把内存分两种:一种是栈内存,另一种是堆内存
(1) 在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配; (2) 堆内存用来存放由new创建的对象和数组以及对象的实例变量。在函数(代码块)中定义一个引用变量时,java就在栈中为这个引用变量分配内存空间,当超过引用变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理堆和栈的优缺点
堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。
缺点就是要在运行时动态分配内存,存取速度较慢;栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。
另外,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
不同数据类型比较采用的稳妥方式:
-
基本类型(short,int,long,byte,char,float,double,boolean)数据存放在栈中,当多个变量都是同一个值的时候,他们指向的栈内存地址是同一个地址。此时==和equals效果相同。
-
包装类型(String,Object)
String 存放在常量池中,和基本数据类似,多变量同值时指向同一个内存地址,但是new String(“123”)时会视为创建Object,用equals比较
String str1 = "Hello"; String str5 = "Hello"; String str2 = new String("Hello"); String str4 = new String("Hello"); String str3 = str2; // 引用传递,同一对象 System.out.println(str1 == str2); // false(str2是new的一个新地址) System.out.println(str1 == str3); // false(str3和str2内存地址一样,和str1地址不同) System.out.println(str2 == str3); // true(引用str2,地址相同) System.out.println(str1 == str5); // true(String作为基本类型,没创建新地址) System.out.println(str4 == str2); // false(内存地址不同) System.out.println(str1.equals(str2)); // true(内容一致,都是“hello”) System.out.println(str1.equals(str3)); // true(内容一致,都是“hello”) System.out.println(str2.equals(str3)); // true(内容一致,都是“hello”) System.out.println(str2.equals(str4)); // true(内容一致,都是“hello”) System.out.println(str1.equals(str5)); // true(内容一致,都是“hello”)
Object 值和内存地址独立存储,一般不会存在同值同地址的情况,此时采用重写equals方法,用equals比较
2. 结论
有equals方法的全用equals比较,没有的用==
有一种情况是对象的比较字段可能为Null,这种情况用equals会导致空指针,需要注意。3. Integer可视为Object,那为什么==会是true?
Integer 内部实现了一个缓存池数值范围为: -128~127. 如果数值超过127, 则会new Integer对象.,所以当对象值在缓存区间范围内时 == 是可以比较的 但是当超过127 ==就会是false,用equal比较稳妥
源码:
public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
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; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { 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); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); }
转载地址:https://cuzue.blog.csdn.net/article/details/123753503 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!