头图

我们都知道 Java 是静态的、强制类型的语言。也就是声明的每个变量都必须声明该变量的类型。

Java 中的变量类型可以分为两类:引用类型(primitive type)和基本类型(reference type)。引用类型 reference to object,基本类型 directly contain value。


public static void main (String[] args) {
    String str = new String("hello"); // 引用类型
    int age = 12; // 基本类型
}

== 比较两个变量是否相等

== 用来比较 Java 变量中值是否相等时,对不同的变量类型有不一样的比较策略。

对于基本类型变量,== 比较的是两个基本类型变量的值是否相等。
对于引用类型变量,== 比较的是两个引用类型变量的地址值是否相等。


public static void main (String[] args) {
    Person person = new Person("xiaoyu", 12);
    Person person1 = new Person("xiaoyu", 12);
    int amount1 = 12;
    int amount2 = 20;
    int amount3 = 12;
    System.out.println(person == person1); // false
    System.out.println(amount1 == amount2); // false
    System.out.println(amount1 == amount3); // true
}

equals 比较两个变量是否相等

equals 方法是 Java 语言中 Object 类(根类)的方法。Java 中所有其他的类都继承自该类。

Object 类中 equals 方法的默认实现是:

/**
 * 比较其他对象与该对象是否相等。默认的比较方式是:== 
*/
public boolean equals(Object obj) {
    return (this == obj);
}

所以,用 equals 方法比较两个变量是否相等的时候,是要看具体的对象所对应的类中的 equals 方法的具体实现的。因为 equals 方法有可能被重写。

String 类就重写了 Object 类的 equals 方法。比较的是两个字符串对象的字符序列是否相等。


/**
 * Compares this string to the specified object.  
 * The result is {@code * true} if and only if 
 * the argument is not {@code null} and is a 
 * {@code * String} object that represents the 
 * same sequence of characters as this object. 
 * 
 * <p>For finer-grained String comparison, refer to
 * {@link java.text.Collator}.
 * 
 * @param anObject
 *   The object to compare this {@code String} against
 * 
 * @return  {@code true} if the given object represents a {@code String} 
 *          equivalent to this string, {@code false} otherwise 
 * 
 * @see  #compareTo(String)
 * @see  #equalsIgnoreCase(String)
 */
 public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String aString = (String)anObject;
        if (coder() == aString.coder()) {
            return isLatin1() ? StringLatin1.equals(value, aString.value)
                              : StringUTF16.equals(value, aString.value);
        }
    }
    return false;
}

企业开发中对两者的运用

知道原理是基础,懂得了原理我们才能在实际开发中更好的运用。

在实际的企业开发中:

  1. 对于基本类型变量的比较,通常使用 == 来进行比较。
  2. 对于字符对象的比较,通常使用 equals 方法来进行比较。
  3. 对于其他类型对象之间,一般建议使用 == 来进行比较,不要使用 equals 来进行比较。因为有可能会造成线上故障。

针对第三个建议,举一个例子来说明原因:


public class TestPackaging {
    public static void main (String[] args) {
        Order order = new Order();
        order.setStatus(Status.New);
        // 使用 equals 来判断是否相等
        if (!Status.New.equals(order.getStatus())) {
            System.out.println("转账100元");
        }
        
    }
}
enum Status {
    New, Created
}
class Order {
    private Status status;
    public Status getStatus() {
        return status;
    }
    public void setStatus(Status status) {
        this.status = status;
    }
}

若有人把 Order 类中的 status 变量的类型改成 String 的话。


class Order {
    private String status;
    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }
}

编辑器在执行静态检查的时候是正常的,是不会报警的。那么下面这段逻辑将永远为 false。如果这条判断语句里执行的是很重要的代码。那么就会造成资损等严重的线上故障。

image.png

使用 == 来比较的话就能避免这种人工很难发现的错误。因为在编译器就会检查出错误。

image.png


余良彬
1 声望0 粉丝