zoukankan      html  css  js  c++  java
  • java中equals()和==的区别

    java中的数据类型

    基础数据类型

    基础数据类型有byte、short、char、int、long、float、double、bool、String。除了 String 会比较地址,其它的基础类型的比较,使用 == 和 equals() 两者都是比较值。

    • String类的equals()方法源码

       1 public boolean equals(Object anObject) {
       2         if (this == anObject) { //先比较地址,如果相同直接返回true
       3             return true;
       4         }
       5         if (anObject instanceof String) {//如果地址不相同,判断要比较的对象是不是String实例,如果不是直接返回false
       6             String anotherString = (String) anObject;
       7             int n = value.length;
       8             if (n == anotherString.value.length) {//比较两个对象的长度,如果不相等直接返回false
       9                 char v1[] = value;
      10                 char v2[] = anotherString.value;
      11                 int i = 0;
      12                 while (n-- != 0) {
      13                     if (v1[i] != v2[i])
      14                         return false;
      15                     i++;
      16                 }
      17                 //比较两个string对象的每个字符,如果都相等,就返回true,有一个不相等就返回false
      18                 return true;
      19             }
      20         }
      21         return false;
      22     }

      查看源码可知,String 类型的 equals 方法既会比较地址,也会比较字符串的每个字符(值).

    • String类型的equals()比较

      1 public class Main {
      2     public static void main(String[] args) {
      3         String name1 = new String("123");
      4         String name2 = new String("123");
      5         System.out.println(name1 == name2);//false
      6         System.out.println(name1.equals(name2));//true
      7     }
      8 }

      结果分析: name1 和 name2 是 String 的两个不同实例,name1==name2 是比较 name1 与 name2 的地址,所以返回 false。而 name1.equals(name2) 先是比较两者的地址,发现不同后接着比较两者的值,相同,所以返回 true。

    复合数据类型(类)

    • Object类中equals()方法源码

      1 public boolean equals(Object obj) {
      2         return (this == obj);
      3     }

      查看源码可知,当自己定义的类如果不重写 Object 类中 equals() 方法时,调用 equals() 方法其实和直接用 == 判断的效果一样。

    • 未重写时

       1 public class Person {
       2     private String name;
       3 
       4     public Person(String name) {
       5         this.setName(name);
       6     }
       7 
       8     public String getName() {
       9         return name;
      10     }
      11 
      12     public void setName(String name) {
      13         this.name = name;
      14     }
      15 }
      Person.java
      1 public class Test {
      2     public static void main(String[] args) {
      3         Person person1 = new Person("zze");
      4         Person person2 = new Person("zze");
      5         System.out.println(person1 == person2);//false
      6         System.out.println(person1.equals(person2));//false
      7     }
      8 }
    • 重写时

       1 public class Person {
       2     private String name;
       3 
       4     public Person(String name) {
       5         this.setName(name);
       6     }
       7 
       8     public String getName() {
       9         return name;
      10     }
      11 
      12     public void setName(String name) {
      13         this.name = name;
      14     }
      15 
      16     @Override
      17     public boolean equals(Object obj) {
      18         if(obj instanceof Person){
      19             return this.name==((Person) obj).name;
      20         }
      21         return false;
      22     }
      23 }
      Person.java
      1 public class Test {
      2     public static void main(String[] args) {
      3         Person person1 = new Person("zze");
      4         Person person2 = new Person("zze");
      5         System.out.println(person1 == person2);//false
      6         System.out.println(person1.equals(person2));//true
      7     }
      8 }

    结论

    首先,基本数据类型与复合数据类型在内存中存储的的方式是不同的:

    • 基本数据类型在栈中存储的是值。
    • 复合数据类型在栈中存储的是地址,来指向堆内存的实例。

    可以这样理解:使用 == 比较的时候都是比较变量中存储的值,但基础类型的变量中存储的值就是实际值,而复合数据类型变量中存储的值是指向堆对象的引用地址。而 equals() 方法就是一个依赖于 == 实现普通函数,只不过它的实现是在所有对象的基类 (Object) 中.

  • 相关阅读:
    [fw]error: aggregate value used where an integer was expected
    [fw]awk求和
    [fw]谈EXPORT_SYMBOL使用
    [fw]用Kprobes调试(debug)内核
    [FW]使用kprobes查看内核内部信息
    linux缺頁異常處理--內核空間[v3.10]
    用C语言给指定的内存地址赋值(通过指针)
    [fw]Linux 的 time 指令
    how to prevent lowmemorykiller from killing processes
    Android成长日记-Noification实现状态栏通知
  • 原文地址:https://www.cnblogs.com/zze46/p/9606339.html
Copyright © 2011-2022 走看看