Java==对于停止工作的字符串对象?

Java==对于停止工作的字符串对象?,java,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)); } }

产出:

  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));
        }
    }

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

=>可以保证文本字符串对象将被运行在同一虚拟机中的任何其他代码重用,而该虚拟机恰好包含它所包含的相同字符串文本。但是字符串文字是合并的,因此
“prova”
返回相同的实例。

您必须了解“==”比较引用,“equals”比较值。
s
s1
都指向相同的字符串文字,因此它们的引用是相同的。

是的,“prova”存储在java内部字符串池中,因此它是相同的引用

源代码文本是的一部分,因此如果同一文本多次出现,则在运行时将是同一对象。

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

true
true

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

JVM可以优化字符串使用,以便内存中只有一个“equal”字符串实例。在这种情况下,==运算符也将返回true。但是不要指望它。

当您在java代码中放入一个文本字符串时,编译器会自动插入该字符串,即创建该字符串的一个静态全局实例。或者更具体地说,它被放入一个内部字符串表中。在内容方面,任何其他完全相同的带引号的字符串都将引用相同的插入字符串


因此,在代码中,s和s2是相同的字符串

,因为
字符串
实例是不可变的,Java语言能够进行一些优化,从而使
字符串
文本(或者更一般地说,
字符串
的值是编译时常量)是内部的,并且实际引用相同的(即
==
)对象

每个字符串文字都是对
类字符串
实例的引用<代码>字符串对象具有常量值。字符串文字,或者更一般地说,作为常量表达式值的字符串,使用该方法被“插入”,以便共享唯一的实例

这就是为什么会出现以下情况:

String s1 = new String("prova");
String s2 = new String("prova");
System.out.println(s1 == s2); // returns false.
也就是说,一般情况下,您不应该依赖
==
进行
字符串
比较,而应该使用
等于
进行非
字符串实例
。特别是,不要试图
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);
new
操作符总是创建一个新对象,因此保证打印
false
。也就是说,这通常不是你真正需要做的事情。只要有可能,您应该只使用字符串文本,而不是显式地为其创建一个
新字符串

相关问题

s
s2
是指向JVM字符串池中相同对象的文本字符串,因此比较返回true。

理想情况下,它永远不会发生。因为java规范保证了这一点。因此,我认为这可能是JVM中的错误,您应该向sun microsystems报告。

+1因为所有答案基本相同,但这一个需要费心解释。因为实现了哪个版本?执行
新字符串(…)
的常见原因是在使用子字符串时。如果您的字符串很大,并且您对其调用substring(),则返回的substring仍将保留对较大原始字符串的引用。在某些情况下,这可能会导致问题和内存泄漏——虽然在代码中不再使用大字符串,但它不是GCed。若要“修复”此问题,可以执行
新建字符串(最大字符串。子字符串(…)
。(我觉得我也应该添加一些有用的评论。)@Peter:是的,这是一个相关的问题(“目的是什么…”)。我曾考虑在这里添加它,但不确定这对初学者来说是否已经太长和/或太混乱了。
System.out.println("x" == new String("x")); // false
String s = "prova";
String s2 = "prova";