“equals”和“==”的区别

    开门见山,当我们比较两个引用是否相同时。需要分情况讨论。

    首先需要补充一点知识点。我们使用“new”关键字的实质是向系统申请一块内存区域来盛放我们所创建的对象。例如下面的语句:

    Demo d1=new Demo();

    这里的d1相当于c语言中的指针(不完全对,但是在这里可以近似这么认为),它指向内存堆空间中一个Demo类的对象(或称一个实例),这个区域的名字记为区域1;

    这时间,如果我们再次使用相同的语句:

    Demo d2=new Demo();

    虽然也是创建了一个Demo类的实例,但是这个对象处在内存中的堆空间中的另一个区域,将这个区域计为区域2.

    我们可以得出一个结论。d1和d2虽然都相当于指针,但是他们指向堆空间中的不同内存区域。

     这里有一个比较容易混淆的情况,当我们不使用new关键字新建对象,而是直接使用等号赋值时,这个值被系统自动“变成”一个对象,但此时,这个对象存放在内存中的常量池中,而不是堆空间中。在常量池中的对象有一个特点,当我们下次以同样不使用new关键字而在常量池中创建一个对象时,若此时我们赋予他的值与内存中已经存在了,就不会再重新申请一块内存,而是直接使这个新的“指针”指向原来已经存在的内存区域。注意看下面的代码:

   String str1="abc";

   String str2="abc";

   String str3="def";

这里没有使用new关键字,而是直接使用“=”赋值,所以会在常量池中创建对像。当str1建立与字符串对象(这个对象的值是abc)建立联系时,首先会检查在常量池中有没有String对象的值是“abc”,当已经有String对象的值是“abc”时,直接使str1指向它,当没有String对象的值是abc时,则在常量池中新申请一块区域,盛放一个新的Sring对象,盛放值“abc”,再使str1指向它。因此,可以得出结论,这里的str1和str2指向常量池中同一块内存区域,而str3则指向常量池中的另一块内存区域。 额

   有了上面的知识点后,下面来讲述“==”和equals方法的区别。

   首先,如果你的“指针”指向的是基本包装类时,“==”比较的是他们是否指向同一块内存区域,而equals方法比较的是这些“指针”所指向的基本包装类的值是否相等(忽略其所在的内存区域)。

public class Demo {

	private static void print(String s){
		System.out.println(s);
	}
	public static void main(String args[]){

		String n1=new String("123");
		String n2=new String("123");		
		String n3=new String("456");
		String n4="123";
		String n5="123";
		print("");
		 
		print("n1和n2指向内存堆空间中不同内存区域:");
		print("n1==n2: "+(n1==n2));
		print("n1和n3指向内存"+ "堆空间中不同内存区域:");
		print("n1==n3: "+(n1==n3));
		print("n4和n5指向内存常量池中同一块内存区域: ");
		print("n4==n5:"+(n4==n5));
		
		
		print("n1和n2指向不同内存区域,但所指对象值相同");
		print("n1.equals(n2): "+n1.equals(n2));
		
		print("n1和n3指向不同内存区域,所指对象值也不相同");
		print("n1.equals(n3): "+n1.equals(n3));
		
	}
}

运行结果如下:



下面讨论第二种情况。当我们的"指针"不是指向基本包装类时,如果这两个”指针“不是指向同一块内存区域时,”==“和”equals“结果均为false。而这两个”指针“指向同一块内存区域时,”==“和”equals“结果均为true。

public class Demo {

	private static void print(String s){
		System.out.println(s);
	}
	public static void main(String args[]){

		Value v1=new Value();
		Value v2=new Value();
		
		v1.i=v2.i=10;
		print("v1==v2: "+(v1==v2));
		print("v1.equals(v2):"+v1.equals(v2));
		
	}
}

运行结果如下:


下面,当我们使v1=v2,即使v1和v2指向同一块内存区域时:

public class Demo {

	private static void print(String s){
		System.out.println(s);
	}
	public static void main(String args[]){

		Value v1=new Value();
		Value v2=new Value();		
		v1=v2;		
		v1.i=v2.i=10;
		print("v1==v2: "+(v1==v2));
		print("v1.equals(v2):"+v1.equals(v2));
		
	}
}
运行结果如下:

所以综上所述,当参与==运算的两个“指针”指向同一块内存区域时,其结果为true(无论是基本包装类还是其余类都适用)。

当调用equals()方法的是基本包装类时,只要n1和n2所指向的基本包装类的值相等,其结果就为true(忽略其实际指向的内存区域)

当调用equals()方法的不是基本包装类时,当且仅当两个引用指向同一块内存区域时,其结果才为true;


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值