> 文档中心 > 【Java基础】equal()与==的用法与区别

【Java基础】equal()与==的用法与区别


1.字符串的创建

我们已经知道声明字符串变量两种方式

// 第一种方式String str = "字符串";// 第二种方式String str = new String("字符串");

两种方式的区别在于第一种方式创建新的字符串,系统会首先在字符串常量池中寻找这个字符串有没有被创建过:

  • 如果这个字符串已经被创建过,那么系统不会再给我们想要创建的字符串变量分配新的内存,而是直接将新建的字符串变量指向已经存在于字符串常量池中的字符串的地址。这就意味着如果我们使用第一种方式声明多个相同的字符串,系统实际上只创建了一个字符串。
  • 如果这个字符串没有被创建过,那么就会为这个字符串开辟新的内存,并且加入字符串常量池。

第二种方式创建新的字符串

  • 使用new关键字创建,会在堆内存开辟一块新的内存用于存放new出来的对象,并且这个字符串并不会被加入到字符串常量池中

关于字符串常量池,总之就是为了避免重复开辟内存空间浪费资源,存放在JVM虚拟机中的堆内存当中,具体我也不了解太多,csdn肯定有别的博主写的很不错的文章,大家可以去看看。

2.==的用法

接下来,我们再来说一下==的用法,==的用途也是比较两个变量是否相等,不过要注意==比较的是两个变量的地址是否相同

String str1 = "测试数据";String str2 = "测试数据";String str3 = new String("测试数据");System.out.println(str1==str2);// trueSystem.out.println(str1.equals(str2));  // trueSystem.out.println(str1==str3);  // falseSystem.out.println(str1.equals(str3));  // true

接下来我们来说明一下5-8行的输出结果为什么会是这样。

  • 第一行(true):str1==str2返回true是因为在str1被创建以后,str2会直接指向常量池中str1的数据,因为“测试数据”这个字符串已经存在字符串常量池中了,既然两者都指向同一个字符串,地址必然相同,自然就返回true了。
  • 第二行(true):String已经重写过equals方法了,所以str1.equals(str2)比较的是字符串的内容,自然会返回true。
  • 第三行(false):两个字符串变量所指向的对象地址并不一样,所以会返回false
  • 第四行(true):虽然两个字符串变量指向的对象地址不一样,但是他们的内容一样,所以会返回false。

3.equals()的用法

下面我们将要分情况讨论:

  • 如果这个类重写了equal()方法

    • 那么会按照这个类重写的equal代码来判断这两个对象是否相等

    • 下面我们用实例来测试:

    • import java.util.Objects;public class Test {    public static void main(String[] args) { Student stu1 = new Student("张三",20); Student stu2 = new Student("张三",20); System.out.println(stu1.equals(stu2));//输出结果为true    }}class Student{    protected String name;    protected int age;    public Student(){    }    public Student(String name, int age){ this.age = age; this.name = name;    }    @Override    public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return age == student.age && Objects.equals(name, student.name);    }    @Override    public int hashCode() { return Objects.hash(name, age);    }}
  • 如果这个类没有重写了equal()方法

    • 那么它的作用就和==一样,只是用来判断两个对象的地址

    • 同样的我们接着上面的例子进行修改测试:

    • public class Test {    public static void main(String[] args) { Student stu1 = new Student("张三",20); Student stu2 = new Student("张三",20); System.out.println(stu1.equals(stu2));//输出结果为false    }}class Student{    protected String name;    protected int age;    public Student(){    }    public Student(String name, int age){ this.age = age; this.name = name;    }}