java字符串相等

java字符串相等,java,string,Java,String,字符串可以通过两种方式初始化: String s="ABCD"; 或 这两个是相同的还是不同的?? 我再次注意到 String s="ABCD"; String z="ABCD"; boolean b=s.equals(z); 结果是真实的,但是 String s=new String("ABCD"); String z=new String("ABCD"); boolean b=s.equals(z); 结果是错误的。 谁能解释一下为什么会发生这种情况 String s="ABCD";

字符串可以通过两种方式初始化:

String s="ABCD";

这两个是相同的还是不同的?? 我再次注意到

String s="ABCD";
String z="ABCD";
boolean b=s.equals(z);
结果是真实的,但是

String s=new String("ABCD");
String z=new String("ABCD");
boolean b=s.equals(z);
结果是错误的。 谁能解释一下为什么会发生这种情况

String s="ABCD";
String z="ABCD";
在内存池中引用相同的字符串。 然而

为字符串生成单独的内存空间。 所以输出是这样的。
这也回答了您的第一个问题。

当我们调用以下语句时

String s="ABCD";
String z="ABCD";
然后,它将在字符串池中进行检查,如果池中已经存在,则地址将引用到变量。

但是当我们调用
new
关键字,然后明确地说要创建新内存。

我不确定这一点,但我在第二个示例中给出了答案

String s=new String("ABCD");
String z=new String("ABCD");

它是像对象一样声明的,因此当您尝试检查相等时,肯定会给出u
false
(对象不能等于对象)

所有示例的结果都必须是
true

为什么??
String
类有一个重写的
equals
方法,用于逐个字符检查两个字符串是否相同。 另一方面,运算符==检查两个字符串引用是否指向同一个对象

例如:

String a = new String("asd"); //new object, will add to pool though
String b = new String("asd"); //new object
String c = "asd"; //will use the pool
boolean b1 = (a == b); //false, different objects (same contents though)
boolean b2 = (a.equals(b)); //true, same contents
boolean b3 = (a == c); //false, different objects
boolean b3 = (a.equals(c)); //true, same contents
需要注意的是,Java使用了字符串池。如果您在代码中的某个地方使用字符串文字,JVM将汇集该值,当您再次在代码中的其他地方使用该值时,JVM将检测到它并将您的引用指向它。字符串是不可变的,因此这是完全安全的

我想强调的最后一件事是构造
stringb=newstring(“asd”)。在这种情况下,将创建一个新的字符串对象(因为运算符
new
)。即使“asd”已经存在于字符串池中,字符串
b
也将指向一个单独的内存位置,其中包含一个新对象

如果池中不存在“asd”,那么不仅将
b
指向非池区,而且还会将“asd”添加到池中,以防万一(供将来参考)。

对不起,但我认为

String s=new String("ABCD");
String z=new String("ABCD");
boolean b=s.equals(z);
它应该是返回真的,请再次检查

您的问题在不同方面是正确的(使用==运算符) 有两种方法可以在Java中创建字符串对象:

  • 使用新操作符。比如说,

    String str=新字符串(“你好”)

  • 使用字符串文字或常量表达式)。比如说,

    String str=“你好”;(字符串文字)或

    String str=“Hel”+“lo”;(字符串常量表达式)。

字符串文字
字符串分配和所有对象分配一样,在时间和内存上都很昂贵。JVM在实例化字符串文本以提高性能和减少内存开销时执行一些技巧。为了减少JVM中创建的字符串对象的数量,String类保留了一个字符串池。每次代码创建字符串文字时,JVM都会首先检查字符串文字池。如果该字符串已存在于池中,则返回对池实例的引用。如果池中不存在该字符串,则会实例化一个新的字符串对象,然后将其放入池中。Java可以进行这种优化,因为字符串是不可变的,可以在不担心数据损坏的情况下共享

从你的问题来看

String s="ABCD";
String z="ABCD";
boolean b=s==z; 
我应该返回
true
,因为两个对象具有相同的引用

但是万一

String s=new String("ABCD");
String z=new String("ABCD");
boolean b = s==z;

它将返回
false
,因为这两个对象是不同的

我建议您必须阅读并分析String.class的源代码,尤其是equals和intern方法,另外您还必须研究java的内存结构

字符串#等于 弦乐实习生 记忆结构

我否认您的前提:两个代码段都将值
true
放在变量中。也许你的意思是
s==z
?我认为这对于发布的代码是不正确的
.equals()
检查相等,而不是标识。池在这里没有效果。内存池的概念是准确的。这对
等于
错误有任何影响的事实并非如此
“ABCD”.equals(新字符串(“ABCD”))
将是
true
。对不起,我是说==而不是.equals()。它们确实在实例化一个
新字符串
,当
字符串
以这种方式声明时,该字符串分配的新内存不会进入全局
字符串
池。所有Java
对象
都有
equals
方法,默认情况下,该方法实际上只执行引用检查(
this==obj
)。但是,
String
,以及许多其他对象,
会覆盖该行为以进行更深入的检查。海报错了;这些物体会说它们是平等的。
String s="ABCD";
String z="ABCD";
boolean b=s==z; 
String s=new String("ABCD");
String z=new String("ABCD");
boolean b = s==z;
/**
 * 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.
 *
 * @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 anotherString = (String)anObject;
    int n = count;
    if (n == anotherString.count) {
    char v1[] = value;
    char v2[] = anotherString.value;
    int i = offset;
    int j = anotherString.offset;
    while (n-- != 0) {
        if (v1[i++] != v2[j++])
        return false;
    }
    return true;
    }
}
return false;
}
/**
 * Returns a canonical representation for the string object.
 * <p>
 * A pool of strings, initially empty, is maintained privately by the
 * class <code>String</code>.
 * <p>
 * When the intern method is invoked, if the pool already contains a
 * string equal to this <code>String</code> object as determined by
 * the {@link #equals(Object)} method, then the string from the pool is
 * returned. Otherwise, this <code>String</code> object is added to the
 * pool and a reference to this <code>String</code> object is returned.
 * <p>
 * It follows that for any two strings <code>s</code> and <code>t</code>,
 * <code>s.intern()&nbsp;==&nbsp;t.intern()</code> is <code>true</code>
 * if and only if <code>s.equals(t)</code> is <code>true</code>.
 * <p>
 * All literal strings and string-valued constant expressions are
 * interned. String literals are defined in &sect;3.10.5 of the
 * <a href="http://java.sun.com/docs/books/jls/html/">Java Language
 * Specification</a>
 *
 * @return  a string that has the same contents as this string, but is
 *          guaranteed to be from a pool of unique strings.
 */
public native String intern();