两者有什么区别
String str = new String("abc");
and
String str = "abc";
两者有什么区别
String str = new String("abc");
and
String str = "abc";
当前回答
以下是一些比较:
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
System.out.println(s1 == s2); //true
System.out.println(s1.equals(s2)); //true
System.out.println(s1 == s3); //false
System.out.println(s1.equals(s3)); //true
s3 = s3.intern();
System.out.println(s1 == s3); //true
System.out.println(s1.equals(s3)); //true
当调用intern()时,引用将被更改。
其他回答
一些拆卸总是很有趣的……
$ cat Test.java
public class Test {
public static void main(String... args) {
String abc = "abc";
String def = new String("def");
}
}
$ javap -c -v Test
Compiled from "Test.java"
public class Test extends java.lang.Object
SourceFile: "Test.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method #7.#16; // java/lang/Object."<init>":()V
const #2 = String #17; // abc
const #3 = class #18; // java/lang/String
const #4 = String #19; // def
const #5 = Method #3.#20; // java/lang/String."<init>":(Ljava/lang/String;)V
const #6 = class #21; // Test
const #7 = class #22; // java/lang/Object
const #8 = Asciz <init>;
...
{
public Test(); ...
public static void main(java.lang.String[]);
Code:
Stack=3, Locals=3, Args_size=1
0: ldc #2; // Load string constant "abc"
2: astore_1 // Store top of stack onto local variable 1
3: new #3; // class java/lang/String
6: dup // duplicate top of stack
7: ldc #4; // Load string constant "def"
9: invokespecial #5; // Invoke constructor
12: astore_2 // Store top of stack onto local variable 2
13: return
}
String字面值是Java语言的一个概念。这是一个String字面值:
"a String literal"
String对象是java.lang.String类的一个单独实例。
String s1 = "abcde";
String s2 = new String("abcde");
String s3 = "abcde";
都是有效的,但有细微的区别。s1将引用一个被压缩的String对象。这意味着,字符序列“abcde”将存储在一个中心位置,无论何时再次使用相同的文字“abcde”,JVM都不会创建一个新的String对象,而是使用缓存的String的引用。
s2肯定是一个新的String对象,所以在这种情况下,我们有:
s1 == s2 // is false
s1 == s3 // is true
s1.equals(s2) // is true
当你使用字符串字面值时,字符串可以被合并,但当你使用new string("…")时,你会得到一个新的字符串对象。
在这个例子中,两个字符串字面值引用同一个对象:
String a = "abc";
String b = "abc";
System.out.println(a == b); // true
这里创建了2个不同的对象,它们有不同的引用:
String c = new String("abc");
String d = new String("abc");
System.out.println(c == d); // false
一般来说,应该尽可能使用字符串文字表示法。它更容易阅读,并给编译器一个机会来优化你的代码。
由于字符串是不可变的,当你这样做时:
String a = "xyz"
在创建字符串时,JVM在字符串池中搜索是否已经存在一个字符串值“xyz”,如果存在,'a'将只是该字符串的引用,并且不会创建新的string对象。
但如果你说:
String a = new String("xyz")
强制JVM创建一个新的String引用,即使"xyz"在它的池中。
要了解更多信息,请阅读这篇文章。
String是Java中不同于其他编程语言的一个类。因此,对于每个类,对象的声明和初始化是
String st1 = new String();
or
String st2 = new String("Hello");
String st3 = new String("Hello");
这里,st1, st2和st3是不同的对象。
那就是:
st1 == st2 // false
st1 == st3 // false
st2 == st3 // false
因为st1, st2, st3引用了3个不同的对象,并且==检查内存位置是否相等,因此得到了结果。
But:
st1.equals(st2) // false
st2.equals(st3) // true
这里.equals()方法检查内容,st1 = "", st2 = "hello"和st3 = "hello"的内容。这就是结果。
在String声明的情况下
String st = "hello";
这里调用String类的intern()方法,检查“hello”是否在实习生池中,如果不在实习生池中,则将其添加到实习生池中,如果实习生池中存在“hello”,则st将指向现有“hello”的内存。
所以在这种情况下:
String st3 = "hello";
String st4 = "hello";
在这里:
st3 == st4 // true
因为st3和st4指向相同的内存地址。
另外:
st3.equals(st4); // true as usual