技术分享
🗒️[实践]谈Java中的比较
00 分钟
2023-12-27
2023-12-27
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")
  1. 当我们使用双引号创建字符串时,Java会首先在字符串常量池中查找是否已经存在值为"kuang"的字符串。如果存在,就直接返回这个字符串的引用;如果不存在,就在字符串常量池中创建一个新的字符串,并返回这个新字符串的引用。这种方式创建的字符串,相同内容的字符串在内存中只有一份,可以节省内存
  1. 当我们使用new关键字创建字符串时,Java会在堆内存中创建一个新的字符串对象,不管字符串常量池中是否已经存在值为"kuang"的字符串。这种方式创建的字符串,即使内容相同,也会在内存中创建多份
在上面的例子中,s7s8s9s10虽然内容相同,但是它们在内存中的位置是不同的。s7是在字符串常量池中创建的,而s8是在堆内存中创建的。System.identityHashCode()方法返回的是对象在内存中的地址,所以s7s8的地址是不同的。
 
🔥
特别注意
在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 类型:
 
上一篇
Day97【概念解析】SWOT Analysis
下一篇
Day96【概念解析】PEST Analysis

评论
Loading...