java - 字符串对象和字符串li之间的区别
这个问题在这里已有答案:
“text”和new String(“text”)之间有什么区别? 9个答案
有什么区别
String str = new String("abc");
和
String str = "abc";
13个解决方案
198 votes
当您使用字符串文字时,字符串可以被实现,但是当您使用new String("...")时,您将获得一个新的字符串对象。
在此示例中,两个字符串文字都引用相同的对象:
String a = "abc";
String b = "abc";
System.out.println(a == b); // true
在这里,创建了两个不同的对象,它们具有不同的引用:
String c = new String("abc");
String d = new String("abc");
System.out.println(c == d); // false
通常,应尽可能使用字符串文字表示法。 它更容易阅读,它为编译器提供了优化代码的机会。
Mark Byers answered 2019-02-18T20:50:52Z
85 votes
String文字是Java语言的概念。 这是一个字符串文字:
"a String literal"
String对象是s2类的单个实例。
String s1 = "abcde";
String s2 = new String("abcde");
String s3 = "abcde";
一切都有效,但略有不同。 s2将引用一个interned String对象。 这意味着字符序列"abcde"将存储在中心位置,并且每当再次使用相同的文字"abcde"时,JVM将不会创建新的String对象,而是使用缓存的String的引用。
s2保证是一个新的String对象,所以在这种情况下我们有:
s1 == s2 // is false
s1 == s3 // is true
s1.equals(s2) // is true
Andreas_D answered 2019-02-18T20:51:38Z
38 votes
这里有很长的答案,所以我会给你一个简短的答案。
当你这样做:
String str = "abc";
您在String上调用==方法。 此方法引用内部池.equals()对象。 如果您调用的字符串Objects已驻留在池中,则对该Object的引用将分配给==.如果不是,则将新的false放入池中,然后将对它的引用分配给str。
给出以下代码:
String str = "abc";
String str2 = "abc";
boolean identity = str == str2;
当您通过执行==检查对象标识时(您实际上是在询问:这两个引用是否指向同一个对象?),您将得到.equals()。
但是,您不需要== .equals().您可以通过执行以下操作强制在堆上的新Objects上创建:
String str = new String("abc");
String str2 = new String("abc");
boolean identity = str == str2;
在本例中,==和.equals()是对不同的Objects的引用,两者都没有被实现,因此当您使用==测试Object身份时,您将获得false。
在良好的编码实践方面:不要使用==来检查字符串是否相等,而是使用.equals()。
Jon answered 2019-02-18T20:52:56Z
32 votes
由于字符串是不可变的,当你这样做时:
String a = "xyz"
在创建字符串时,如果已存在字符串值String,JVM将在字符串池中搜索,如果是,则"xyz"将只是该字符串的引用,并且不会创建新的String对象。
但如果你说:
String a = new String("xyz")
你强制JVM创建一个新的String引用,即使它的池中有"xyz"。
欲了解更多信息,请阅读
awin answered 2019-02-18T20:53:49Z
17 votes
new String("abc")是一个文字字符串。
在Java中,这些文字字符串在内部汇集,并且在您的代码中声明了字符串文字的地方使用了相同的字符串实例new String("abc")。 所以"abc"将永远为真,因为它们都是相同的String实例。
使用new String("abc")方法,您可以将任何您喜欢的字符串添加到内部池化的字符串中,这些字符串将保留在内存中,直到java退出。
另一方面,使用new String("abc")将在内存中创建一个新的字符串对象,这在逻辑上与"abc"文字相同。"abc" == new String("abc")将始终为false,因为尽管它们在逻辑上相等,但它们指的是不同的实例。
围绕字符串文字包装String构造函数是没有价值的,它只是不必要地使用了比它需要的更多的内存。
krock answered 2019-02-18T20:54:43Z
7 votes
String是Java中与其他编程语言不同的类。 因此对于每个类,对象声明和初始化是
String st1 = new String();
要么
String st2 = new String("Hello");
String st3 = new String("Hello");
这里,.equals(),st1 = ""和st3是不同的对象。
那是:
st1 == st2 // false
st1 == st3 // false
st2 == st3 // false
因为.equals(),st1 = "",st3正在引用3个不同的对象,并且==检查存储器位置的相等性,因此得到结果。
但:
st1.equals(st2) // false
st2.equals(st3) // true
这里.equals()方法检查内容,并且内容为st1 = "",st3和st4。因此得到结果。
并且在String声明的情况下
String st = "hello";
这里,调用st3类的st3方法,并检查"hello"是否在实习池中,如果没有,则将其添加到实习池中,如果实际池中存在“hello”,则st将指向现有内存"hello"。
所以在以下情况下:
String st3 = "hello";
String st4 = "hello";
这里:
st3 == st4 // true
因为st3和st4指向相同的内存地址。
也:
st3.equals(st4); // true as usual
NCA answered 2019-02-18T20:56:09Z
6 votes
在第一种情况下,创建了两个对象。
在第二种情况下,它只是一个。
尽管两种方式str均指"abc"。
sushil bharwani answered 2019-02-18T20:56:53Z
5 votes
一些拆卸总是很有趣......
$ 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."":()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."":(Ljava/lang/String;)V
const #6 = class #21; // Test
const #7 = class #22; // java/lang/Object
const #8 = Asciz ;
...
{
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
}
aioobe answered 2019-02-18T20:57:24Z
5 votes
除了已经发布的答案,还可以看到关于javaranch的这篇优秀文章。
Zaki answered 2019-02-18T20:57:55Z
3 votes
根据String类文档,它们是等效的。
String(String original)的文档也说:除非需要显式的原始副本,否则不必使用此构造函数,因为字符串是不可变的。
寻找其他响应,因为Java文档似乎具有误导性:(
Michał Niklas answered 2019-02-18T20:58:41Z
2 votes
以下是一些比较:
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()时,引用被更改。
JavaFreak answered 2019-02-18T20:59:18Z
1 votes
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将创建一个新的String对象在普通(非池)内存中,s将引用它。 另外,字面意思是“abc”放在游泳池里。
Kamal answered 2019-02-18T21:00:02Z
0 votes
new String("FFFF")创建2个对象:"FFFF"字符串和String对象,它指向"FFFF"字符串,所以它就像指针指针(引用引用,我不热衷于术语)。
据说你永远不应该使用new String("FFFF")
foret answered 2019-02-18T21:00:46Z