JAVA数据类型比较==与equals浅析

JAVA数据类型比较==与equals浅析

引言

我们知道,String在JAVA中不是作为基本数据类型而存在的,它是一种被封装的类。而在比较两个字符串是否相等的时候,我们需要使用其自带方法equals。可是在这里为什么我们不能使用==呢?

我们先看一段代码

String str1="Hello";
String str2=new String("Hello");
String str3="Hello";

System.out.print("str1==str2:");
System.out.println(str1==str2);
System.out.print("str1==str3:");
System.out.println(str1==str3);
System.out.print("str2==str3:");
System.out.println(str2==str3);

此时输出,将会得到

str1==str2:false
str1==str3:true
str2==str3:false

这就会引出我们接下来的话题,JAVA中对不同数据类型的比较方式。

基于数据类型的==比较符

对于上面的实例最简单的一种解释方式是这样的,JAVA中==比较符号比较的是两个对象是否指向一个内存地址,即两个对象是否为一个引用(因为JAVA避讳指针这一说法,故不采用C语言的解释方法)。

对于str1与str3,我们是直接将字符串面量赋予给它,所以它们此时指向的是内存中的同一个地方,是一样的引用。所以==判断将会返回true,而str2采用new操作告诉了编译器用户想要的是一个全新的字符串,此时它会开辟另一块内存,导致与str1与str2非同一个引用,==返回false

那么对于基本数据类型又是否如此呢?我们对于简单的例子:

int a=1;
int b=1;
a==b;

此时采用引用的解释方式也仍然行得通,因为JVM会缓存JAVA中基本数据类型的常量值,所以a与b此时的确指向一个引用。

但是如果碰到这样的情况:

int a=3;
double b=3.0;
System.out.println(a==b);

显然此时a b所指向的并不是同一个引用,但是返回的结果是true。所以JAVA中的==符号的比较方式根据数据类型的不同将会发生变化,其特点是:

1.当操作数为基本数据类型时,编译时将会生成if_icmpne指令,此时比较的是内存中的数据是否相等

2.当操作数为对象时,编译器会生成if_acmpne指令,其比较的是两者是否为同一个引用。

使用equals

为了防止不能比较两个对象的情况出现,一般来说数据类型的对象一般都会提供equals这一方法。而equals的底部实现仍然是调用==运算符进行数据的比较,以实现对比两个对象是否相等。

以下是String的equals实现:

equals

在本文开始所给出的例子中,可能会让人产生一种错觉,就是如果两个对象是由赋值符号=所构建的话,那么==的比较将会总是返回true。但是这却也并不是总是正确的。例如以下这个例子:

Integer a=127;
Integer b=127;
System.out.println(a==b);
Integer c=129;
Integer d=129;
System.out.println(c==d);

此时返回的结果是:truefalse。这种情况的出现是由于JVM会对Integer类型的 -128~127 的常量值进行缓存,所以当数据范围超过时将会自动new一个新的。但是这个例子换成int的话却会在值相等时总是返回true

总结

JAVA不像C#一样真正的万物皆对象,实际上有一些trick。从本质上来说这一切都是由JVM决定的,而我们需要记住的就只是:使用==比较基本数据类型,而使用equals比较对象,并且遵循这一法则记得实现自己的equals。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值