java中.equals()方法和==号的区别

主方法要进栈

==号和equals()方法都是比较是否相等的方法,那它们有什么区别和联系呢? 
首先,==号在比较基本数据类型时比较的是值,而用==号比较两个对象时比较的是两个对象的地址值,实际上.equals()方法比较的就是相当于把变量进行打包,就是比较包里面的内容:

int x = 10;
int y = 10;
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(x == y); // 输出true
System.out.println(str1 == str2); // 输出false

       那equals()方法呢?我们可以通过查看源码知道,equals()方法存在于Object类中,因为Object类是所有类的直接或间接父类,也就是说所有的类中的equals()方法都继承自Object类,而通过源码我们发现,Object类中equals()方法底层依赖的是==号,那么,在所有没有重写equals()方法的类中,调用equals()方法其实和使用==号的效果一样,也是比较的地址值,然而,Java提供的所有类中,绝大多数类都重写了equals()方法,重写后的equals()方法一般都是比较两个对象的值;

这个是.equals()方法的源码:(所以说如果不重写的话底层架构还是用==的)

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

然后我下面列出我的测试代码:

package com.heima.string;

public class Demo2_String2 {
	
	public static void main(String[] args) {
		//demo1();
		//创建了两个对象,一个在常量池中,还有一个在堆内存中
		//demo2();
		//demo3();
		//demo4();
		demo5();
	}

	private static void demo5() {
		String s1 = "ab";
		String s2 = "abc";
		String s3 = s1 + "c";
		System.out.println(s3 == s2);//false
		System.out.println(s3.equals(s2));//true
	}

	private static void demo4() {
		String s1 = "a" + "b" + "c";
		String s2 = "abc";
		System.out.println(s1 == s2);//true,在java中有常量优化机制
		System.out.println(s1.equals(s2));//true
	}

	private static void demo3() {
		String s1 = new String("abc");//记录的是堆内存中的地址值
		String s2 = "abc";//记录的是常量池中的地址值
		System.out.println(s1 == s2);//false
		System.out.println(s1.equals(s2));//true
	}

	private static void demo2() {
		String s1 = new String("abc");
		System.out.println(s1);//abc
	}

	private static void demo1() {
		String s1 = "abc";
		String s2 = "abc";
		System.out.println(s1 == s2);//true
		System.out.println(s1.equals(s2));//true
	}
}

在demo1中:这就涉及到了内存中的常量池,常量池属于方法区的一部分,当运行到s1创建对象时,如果常量池中没有,就在常量池中创建一个对象”abc”,第二次创建的时候,就直接使用,所以两次创建的对象其实是同一个对象,它们的地址值相等。

所以两个都是为true的;

在demo2中:

创建了两个对象,一个在常量池中,一个在堆内存中;

在demo3中:

s1记录的是堆内存的地址,s2是在常量池中;

在demo4中:

是常量优化原则;

扫描二维码关注公众号,回复: 4135817 查看本文章

在demo5中:

猜你喜欢

转载自blog.csdn.net/rnzhiw/article/details/82694447