Java == for String对象停止工作?

gio*_*oni 11 java

  public class Comparison {
        public static void main(String[] args) {
            String s = "prova";
            String s2 = "prova";
            System.out.println(s == s2);
            System.out.println(s.equals(s2));
        }
    }
Run Code Online (Sandbox Code Playgroud)

输出:

true
true
Run Code Online (Sandbox Code Playgroud)

在我的机器上.为什么?不应该==比较对象引用相等?

pol*_*nts 32

由于 String 实例是不可变的,Java语言能够做出一些优化,从而String文字(或更一般地,String其值编译时间常数)被拘留,实际上指的是相同的(即==)对象.

JLS 3.10.5字符串文字

每个字符串文字都是对实例的引用class String.String对象具有常量值.字符串文字 - 或者更一般地说,是作为常量表达式值的字符串 - 是"实例化"以便使用该方法共享唯一实例String.intern.

这就是为什么你得到以下内容:

System.out.println("yes" == "yes"); // true
System.out.println(99 + "bottles" == "99bottles"); // true
System.out.println("7" + "11" == "" + '7' + '1' + (char) (50-1)); // true
System.out.println("trueLove" == (true + "Love")); // true
System.out.println("MGD64" == "MGD" + Long.SIZE);
Run Code Online (Sandbox Code Playgroud)

也就是说它需要说,你应该依赖==String一般的比较,而应该使用equals针对非null instanceof String.特别是,不要被intern()你的所有人所吸引,String这样你就可以在==不知道字符串实习如何工作的情况下使用.

相关问题


new String(...)

如果由于某种特殊原因你需要创建两个 String 对象(因此不是==按照定义),然而equals你可以使用这个构造函数:

public String(String original):初始化新创建的String对象,使其表示与参数相同的字符序列; 换句话说,新创建的字符串是参数字符串的副本.除非需要显式的原始副本,否则不必使用此构造函数,因为它Strings是不可变的.

因此,您可以:

System.out.println("x" == new String("x")); // false
Run Code Online (Sandbox Code Playgroud)

new操作者总是创建一个新对象,因此上述被保证打印false.也就是说,这通常不是你真正需要做的事情.只要有可能,您应该只使用字符串文字而不是显式创建new String它.

相关问题

  • +1,因为所有的答案基本相同,但这个问题很难解释. (4认同)
  • 执行`new String(...)`的常见原因是使用子串时.如果您的String很大,并且您在其上调用substring(),则返回的子字符串仍将保留对大型原始字符串的引用.在某些情况下,这可能会导致问题和内存泄漏 - 虽然您不再在代码中使用它,但大型字符串不会被GC.要"修复"这个,你可以做`new String(largeString.substring(...))`.(我觉得我应该添加一些有用的评论). (2认同)

Man*_*lva 11

JLS,3.10.5 =>保证文本字符串对象将被同一虚拟机中运行的任何其他代码重用,这些代码恰好包含相同的字符串文字


Lam*_*bda 5

如果显式创建新对象,则==返回false:

String s1 = new String("prova");
String s2 = new String("prova");
System.out.println(s1 == s2); // returns false.
Run Code Online (Sandbox Code Playgroud)

否则JVM可以使用相同的对象,因此s1 == s2将返回true.