string对象和string之间的区别

有什么区别

String str = new String("abc"); 

 String str = "abc"; 

当你使用一个string时,string可以被拦截 ,但是当你使用new String("...")你会得到一个新的string对象。

在这个例子中,两个string文字都引用同一个对象:

 String a = "abc"; String b = "abc"; System.out.println(a == b); // true 

这里创build了2个不同的对象,它们有不同的引用:

 String c = new String("abc"); String d = new String("abc"); System.out.println(c == d); // false 

一般来说,应尽可能使用string文字符号。 它更容易阅读,并使编译器有机会优化您的代码。

一个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将不会创build新的String对象,而是使用caching的 String的引用。

s2保证是一个新的String对象 ,所以在这种情况下我们有:

 s1 == s2 // is false s1 == s3 // is true s1.equals(s2) // is true 

在这里可以find很长的答案,所以我会给你一个短的答案。

当你这样做:

 String str = "abc"; 

您正在调用String上的intern()方法。 这个方法引用一个 String对象的内部池 。 如果您调用intern()的string已经驻留在池中,那么将该String的引用赋值给str 。 如果没有,那么新的String被放置在池中,然后对它的引用被分配给str

给出以下代码:

 String str = "abc"; String str2 = "abc"; boolean identity = str == str2; 

当你通过执行==检查对象的身份(你真的在问:这两个引用指向同一个对象吗?),你会得到true

但是,你不需要 intern() Strings 。 您可以通过执行以下操作在堆上的新Object上强制创build:

 String str = new String("abc"); String str2 = new String("abc"); boolean identity = str == str2; 

在这种情况下, strstr2是对不同Objects引用,这两个Objects都没有被执行 ,所以当你使用==testingObject标识时,你将会得到false

在良好的编码实践方面:不要使用==来检查string是否相等,而是使用.equals()

由于string是不可变的,当你这样做的时候:

 String a = "xyz" 

在创buildstring时,JVM在string池中search是否已经存在string值"xyz" ,如果是这样'a'话,那么'a'只是该string的引用,并且不会创build新的string对象。

但是如果你说:

 String a = new String("xyz") 

您强制JVM创build一个新的String引用,即使"xyz"在其池中。

欲了解更多信息,请阅读。

"abc"是一个文字string。

在Java中,这些文字string在内部汇集,并且使用相同的string"abc"实例,您可以在代码中声明string字面值。 所以"abc" == "abc"将始终为真,因为它们都是相同的String实例。

使用String.intern()方法,您可以将任何string添加到内部共用string中,这些string将保留在内存中,直到java退出。

另一方面,使用new String("abc")将在内存中创build一个新的string对象,这在逻辑上与"abc"字面值相同。 "abc" == new String("abc")将始终为false,因为尽pipe它们在逻辑上相同,但它们指的是不同的实例。

围绕string包装一个String构造函数是没有价值的,它只是不必要地使用了比需要更多的内存。

string是Java中与Java语言不同的一类。 所以每个类的对象声明和初始化都是这样的

 String st1 = new String(); 

要么

 String st2 = new String("Hello"); String st3 = new String("Hello"); 

这里, st1st2st3是不同的对象。

那是:

 st1 == st2 // false st1 == st3 // false st2 == st3 // false 

因为st1st2st3引用3个不同的对象,并且==检查内存位置的相等性,所以结果是。

但:

 st1.equals(st2) // false st2.equals(st3) // true 

这里.equals()方法检查内容,并且st1 = ""st2 = "hello"st3 = "hello" 。 因此,结果。

而在String声明的情况下

 String st = "hello"; 

在这里,调用String类的intern()方法,并检查"hello"是否在intern池中,如果没有,则将其添加到intern池中,如果intern池中存在“hello”, st将指向记忆现有的"hello"

所以在下列情况下:

 String st3 = "hello"; String st4 = "hello"; 

这里:

 st3 == st4 // true 

因为st3st4指向相同的内存地址。

也:

 st3.equals(st4); // true as usual 

在第一种情况下,创build了两个对象。

在第二种情况下,这只是一个。

尽pipe两种方式都是指"abc"

一些反汇编总是有趣的…

 $ 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 } 

除了已经发布的答案之外,在javaranch上也可以看到这篇优秀的文章。

根据String类文档,它们是等价的。

String(String original)文档还说: 除非需要显式拷贝原始文件,否则不需要使用这个构造函数,因为string是不可变的。

寻找其他答案,因为看起来Java文档是误导性的:(

以下是一些比较:

 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()被调用时,引用被改变。

String对象和string之间存在细微差别。

 String s = "abc"; // creates one String object and one reference variable 

在这种简单的情况下,“ abc ”将进入池中, s将引用它。

 String s = new String("abc"); // creates two objects,and one reference variable 

在这种情况下,因为我们使用了new关键字,所以Java将在普通(非池)内存中创build一个新的String对象, s将引用它。 另外,文字“ abc ”将被放置在池中。

String s = new String("FFFF")创build2个对象: "FFFF"string和String对象,它们指向"FFFF"string,所以它就像指向指针的指针(引用引用,我不热衷于术语)。

据说你不应该使用new String("FFFF")