-
Java各种数据类型奇奇怪怪的比较问题
1.关于"=="和"equals"关于引用变量比较时的异同
在大多数情况下,"=="和"equals"在比较引用变量时的效果是相同的,其都是在比较该引用变量在内存中的地址。
使用new 关键字创建的两个Integer对象即使值是相同的,其在使用"=="作比较时的结果也为false,因为这两个变量的内存地址并不相同
但使用equals比较时的结果却为true,因为Integer类中重写了equals方法,使得equals比较的是这两个类中的值是否相等
2.Integer在自动装箱时引发的比较问题
在Java5之后,基本类型和包装类型之间可以进行自动转换
自动装箱使用了 Integer.valueOf() 方法,自动拆箱使用了 Integer.intValue() 方法
但自动装箱时使用的了Integer.valueOf()方法则导致了某些问题:
该方法的源代码如下:
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
当整数基本类型进行自动装箱时,JVM会先判断该数值是否在IntegerCache的范围之内,而这就是导致自动装箱比较出现非预期问题的原因
当被转换的整数在-128和127的范围内时,Java会直接使用缓存中的对象,所以以下代码比较的结果为true
1 Integer a = 100; 2 Integer b = 100; 3 System.out.println(a == b); //结果为true
3.String字符串的比较问题
String与其他引用变量不同的一点是
使用=创建字符串时,也是在内存空间中new一段新空间存放字符串变量,但使用=和new两种方法创建字符串变量有些细微的区别
Java会在字符串常量池中存储该字符串对象,之后如果再创建了值相同的字符串对象,其指向的引用地址为常量池中的对象,也就是只创建了一个相同的字符串对象
试判断两个变量比较的结果
1 String a = "abc"; 2 String b = "ab"; 3 String c = b + "c"; 4 System.out.println(a == c);
答案是false
因为String在进行拼接时,Java内部其实是将String对象转换成了StringBuffer,再使用其append方法进行拼接,最后再使用toString方法转换为字符串,故两者的内存地址并不相同
但试判断接下来的结果
String a = "abc"; String b = "a + b + c"; System.out.println(a == b);
答案是true,这里涉及到了JVM的字符串常量优化机制,在编译的时候,多个字符串常量相拼接,就会在编译阶段被直接拼接,也就是字符串b在编译阶段就已经变成了"abc",运行时a与b同时指向常量池的对象,故地址相等
原文:https://www.cnblogs.com/shiinahikari/p/javase_some_compare_issues.html