细说==和equals的区别

从内存角度说:除去String,==是比较两个对象的地址,也就是栈中的内容是否相同;equals则是比较两个对象堆中的内容是否相同。
从实用角度说:
==对于基本数据类型来说,比较的是左右两边值否相等。
==对于引用类型来说,比较左右两边的引用是否指向同一个对象。
从内存角度理解难一些,从实用角度理解很容易。

8种基本数据类型的数据是存储在栈中,栈里的数据是共享的。
引用类型数据,引用是存储在栈中,对象而存储在堆中。
(关于java各种数据类型在堆栈里怎么存储的问题,可以参考本人的另一篇博文,里面有详细的说明,地址:http://blog.csdn.net/onezg/article/details/53079886

举几个例子说明一下:

int a = 1;
int b = 1;
int c = 2;
System.out.println(a == b);
System.out.println(a == c);

结果为true、false
int a=1; 这行代码会在栈里开辟一块内存,把1存进去,a指向1,int b=1; 这行代码会在栈里寻找有没有1,发现有就会直接使用(栈里的数据共享),b也指向了1,也就是说a和b的地址相同,a==b 比较的是a和b的地址,所以为true。int c=2; 这行代码在栈里寻找2这个数据,发现没有,就会新开辟一块内存,把新值2存进去,c指向了2。a==c, a和c的地址不同,所以为false。

public Class Peron {
    private int IdCardNumber;
    private String name;

    //构造方法省略了
    //...
}

Person p1 = new Person("1", "onezg");
Person p2 = new Person("1", "onezg");
System.out.println(p1 == p2);
System.out.println(p1.equals(p2));

结果为false、false
new创建的对象都是放在堆里,两个对象都放在堆里,而p1和p2两个引用对象都放在栈里,p1和p2指向了两个不同的对象,所以p1和p2地址肯定不同。==比较了p1和p2的地址是否相同,所以结果为false。
为什么p1.equals.(p2)也为false呢?那是因为Person类没有实现equals方法,p1.equals(p2)的这个equals方法实际上是调用了Object类里的equals方法(在Java里所有默认每一个类都继承Object类),Object类里equals方法等价于==(不妨去看看Object源码),所以结果也是false。
equals要想为true,Person类得实现自己的equals,好让Java知道比较的是什么,需要重写equals和hashCode方法(一般都用IDE生成)。

在==和equals区别方面,在Java里有个类特别,那就是String,这里单独提出来说一下。为什么说它特别呢?那就是在JVM设定里有个字符串常量池的概念。
先说字符串常量池的工作原理:
当代码中出现字面赋值方式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用。

String有字面值方式赋值和new方式赋值两种。
第1种,字面值方式赋值。

String a = "hello";
String b = "hello";
System.out.println(a == b);
System.out.pringlnt(a.equals(b));

结果为true、true
String a=”hello”,JVM在字符串常量池里没有找到内容为hello的字符串对象存在,那么会创建这个字符串对象,然后将刚创建的对象的引用放入到字符串常量池中,并且将引用返回给a。Strring b=”hello”,JVM通过查找字符串常量池,发现内容为hello字符串对象存在,于是将已经存在的字符串对象的引用返回给变量b。a和b的地地址相同,所以a==b为true。
a.equals(b)比较的a和b的内容是否相同,可看JDK源码里String的equals方法,结果为true。

第2种,new方式赋值。
这个没什么说的,和new普通对象一样。

String a = new String("world");
String b = new String("world");
System.out.println(a == b);
System.out.println(a.equals(b));

结果为false、true
这个就不多说了,和上面new Person那段一样。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值