type
status
date
slug
summary
tags
category
icon
password
今天CR代码时,看到有人使用
!=
来比较 Integer
类型以及String
类型的大小,编译器提示:
Number object are compared using ‘!=’, not ‘equals()’
,今天就来说说 Java中的类型比较吧。相等比较
为什么不能使用
!=
或者 ==
来比较 Integer 和 String 是否相等?!=
或者 ==
使用时,实际上比较的是两个对象的引用是否相同,如果不是同一个引用的话,会返回不符合预期的结果。示例1:
示例2:
原理分析
对于经常使用C++的同学来说,很容用错。
在 Java 中,对于基本类型的比较,可以直接使用
!=
或者 ==
。Integer
是 基本类型 int
的包装类型,是一个对象。String
也是对象,使用 !=
或者 ==
都是比较对象的引用而不是实际的值,所以逻辑上会有问题。可以看到,i5 和 i6 两者的地址是不一样的,所以比较的话,使用
==
肯定是返回 false 了。同理,s7 和 s8 也是不一样的。
在Java中,字符串有两种创建方式:一种是直接使用双引号创建,如
String s7 = "kuang"
;另一种是通过new
关键字创建,如 String s8 = new String("kuang")
。- 当我们使用双引号创建字符串时,Java会首先在字符串常量池中查找是否已经存在值为"kuang"的字符串。如果存在,就直接返回这个字符串的引用;如果不存在,就在字符串常量池中创建一个新的字符串,并返回这个新字符串的引用。这种方式创建的字符串,相同内容的字符串在内存中只有一份,可以节省内存。
- 当我们使用
new
关键字创建字符串时,Java会在堆内存中创建一个新的字符串对象,不管字符串常量池中是否已经存在值为"kuang"的字符串。这种方式创建的字符串,即使内容相同,也会在内存中创建多份。
在上面的例子中,
s7
、s8
、s9
、s10
虽然内容相同,但是它们在内存中的位置是不同的。s7
是在字符串常量池中创建的,而s8
是在堆内存中创建的。System.identityHashCode()
方法返回的是对象在内存中的地址,所以s7
和s8
的地址是不同的。特别注意
在Java中,
Integer
是一个类,用于封装基本数据类型int
的数据。Integer
的值是不可变的,一旦创建,其值就不能改变。Java为了提高性能和减少内存消耗,对-128到127之间的
Integer
对象进行了缓存,这些对象在Java虚拟机启动时就已经创建好了。当我们调用Integer.valueOf()
方法或者直接赋值(如Integer i = 127
)时,如果值在-128到127之间,Java就会直接返回缓存中的对象,而不是新创建一个对象。这就是为什么在这个范围内,两个相同值的Integer
对象的System.identityHashCode()
返回的值是相同的。然而,对于超过这个范围的值,如129,Java会新创建一个
Integer
对象。所以,即使两个Integer
对象的值相同,它们在内存中的地址也是不同的,System.identityHashCode()
返回的值也是不同的。正确使用方法?
使用
equals
,它比较的是两个对象的值是否一致。Integer 类型:
String 类型:
- 作者:eachenkuang
- 链接:https://kuangyichen.com/article/java-compare
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。