簡體   English   中英

JShell / Java 9中的相等性是怎么回事?

[英]What is going on with equality in JShell/Java 9?

我一直在使用JShell來測試它,今天我遇到了相當有趣的行為。

jshell> String a = "A"
a ==> "A"

jshell> String b = "A"
b ==> "A"

jshell> a == b
$4 ==> true

jshell> "A" == "A"
$5 ==> true

我首先想知道這是否是Java 9的一個功能,我通過使用Java 9編譯和運行該程序來檢查它

public class Equus {
    public static void main(String... args) {
        String a = "A";
        String b = "A";
        System.out.println("a == b");
        System.out.println(a == b);
        System.out.println("\"A\" == \"A\"");
        System.out.println("A" == "A");
    }
}

有趣的是,我得到了

 a == b true "A" == "A" true 

作為我的輸出也是如此。 這里發生了什么? 為什么ab彼此相等,為什么"A" == "A"真的?

為什么不應該呢? 此行為也在以前的Java版本中展示 - 字符串文字被實現。

如您所知, ==檢查引用相等性 - 兩個變量具有相同的內存地址。 當一個String被實現時,該字符串的所有引用都指向實習池,因此使用==將是相等的。

我只是想把這個演示與Sinkingpoint的精彩答案一起添加。
在字符串上使用==是不安全的,除非你知道每個字符串的來源,因為以某種方式構建的字符串(例如Eli評論中的new String("A")或此處使用的.toString() )即使兩者使用相同的底層字符數組,也不是相同的引用

class Main
{
  public static void main(String[] args)
  {
    String oneA = "A";
    String twoA = "A";
    String three = new StringBuilder().append('A').toString();

    // We expect constant literals to be ==
    System.out.print("A == A -> ");
    System.out.println("A" == "A");

    // Variables assigned the same literal are also ==
    System.out.print("oneA == twoA -> ");
    System.out.println(oneA == twoA);

    // but a built-up String var is not == to the "literal" var.
    System.out.print("oneA == three -> ");
    System.out.println(oneA == three);

    // If we intern() them they are again ==
    System.out.print("oneA.intern() == three.intern() -> ");
    System.out.println(oneA.intern() == three.intern());

    // and of course, .equals() is always safe.
    System.out.print("oneA .equals three -> ");
    System.out.println(oneA.equals(three));
  }
}

此輸出(在https://repl.it/languages/java上運行)是:

A == A -> true
oneA == twoA -> true
oneA == three -> false
oneA.intern() == three.intern() -> true
oneA .equals three -> true

您可以安全地使用string1.equals(string2)string1.intern() == string2.intern()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM