VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Java教程 >
  • 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

 


相关教程