欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java中equals与==区别

程序员文章站 2022-06-23 10:49:04
...

关系操作符 ==

首先Java中的数据类型分为

  • 基本类型
  • 引用类型

Java中equals与==区别

在Java中有八种基本数据类型:

  • 浮点型:float(4 byte), double(8 byte)
  • 整型:byte(1 byte), short(2 byte), int(4 byte) , long(8 byte)
  • 字符型: char(2 byte)
  • 布尔型: boolean(JVM规范没有明确规定其所占的空间大小,仅规定其只能够取字面值”true”和”false”)

对于这八种基本数据类型的变量,变量直接存储的是“值”。

所以,在八种基本类型中使用关系操作符 == 来进行比较时,比较的就是“值”本身。

除了基本类型,Java中还有引用类型 

在Java中,引用类型的变量存储的并不是“值”本身,而是与其关联的对象在内存中的地址

比如下面这行代码

String str1;

  这句话声明了一个引用类型的变量,此时它并没有和任何对象关联。 
  而通过 new 来产生一个对象,并将这个对象和str1进行绑定:

str1= new String("hello");

  那么 str1 就指向了这个对象,此时引用变量str1中存储的是它指向的对象在内存中的存储地址,并不是“值”本身,也就是说并不是直接存储的字符串”hello”。这里面的引用和 C/C++ 中的指针很类似。

小结

 因此,对于关系操作符 ==:

  • 若操作数的类型是基本数据类型,则该关系操作符判断的是左右两边操作数的是否相等
  • 若操作数的类型是引用数据类型,则该关系操作符判断的是左右两边操作数的内存地址是否相同。也就是说,若此时返回true,则该操作符作用的一定是同一个对象。

equals方法

1、来源 

  equals方法是基类Object中的实例方法,因此对所有继承于Object的类都会有该方法。 

2、equals方法的作用 

 为了更直观地理解equals方法的作用,我们先看Object类中equals方法的实现。

public boolean equals(Object obj) {
    return (this == obj);
}
通过代码可以看到,Object类里的equals方法也就是直接使用==。

 但我们都知道,下面代码输出为 true:

public class Main {
   public static void main(String[] args) {
       String str1 = new String("hello");
       String str2 = new String("hello");
       System.out.println(str1.equals(str2));
    }
}

再看一下String类的equals方法

public boolean equals(Object anObject) {
    // 先比较两个对象对否指向同一个内存地址
    // 如果相等直接返回true
    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;
            // 逐字符判断是否相等,如果有一个字符不相等,则返回false
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            // 如果所有字符都相等,则返回true
            return true;
        }
    }
    // 如果类型不相等,直接返回false
    return false;
}

可以看到String重写了equals()方法

使用equals方法,内部实现分为三个步骤:

  1. 比较引用是否相同(是否为同一对象)
  2. 判断类型是否一致
  3. 判断长度是否一致
  4. 比较内容是否一致

小结

  • String重写了equals()方法
  • 在String中使用equals()时比较的是字符串的值是否相等

------------------------------------------------------------------------------------------

String对象的创建有两种方式

方法一

对象不同,内容相同

"=="返回false,equals返回true

String s1 = new String("java");
String s2 = new String("java");
System.out.println(s1==s2);            //false
System.out.println(s1.equals(s2));    //true

同一对象

"=="和equals结果相同

String s1 = new String("java");
String s2 = s1;
System.out.println(s1==s2);            //true
System.out.println(s1.equals(s2));    //true

方法二

如果值不相同,则肯定不是相同的对象

所以在这种情况下"==" 和equals结果一样

String s1 = "java";
String s2 = "java";
System.out.println(s1==s2);            //true
System.out.println(s1.equals(s2));    //true

使用方法二创建String时,首先冲缓冲池中找有没有相同的值,如果有则直接指向它。所以这里s1==s2为true

小结

两个语句都是返回一个String对象的引用, 但JVM处理的方式不一样.

  • 方法一: JVM 马上在堆区中创建String对象, 然后将对象的引用返回.(并不会添加至 String Pool 中, 除非显示的调用 String的intern方法)
  • 方法二: JVM 首先在 String Pool 中通过String的 equals 方法查找对象池中是否有该String对象. 如果有,则直接返回而不会再重新创建; 如果没有, JVM 则在堆区中创建新的String对象, 将其引用返回, 同时将该引用添加至String Pool中.
String Pool不是在堆区,也不是在栈区,而是存在于方法区(Method Area)
相关标签: Java基础