2013-07-05 122 views

回答

277

Java String is Special

的Java的设计者决定在面向对象的语言,保留原始类型,而不是使一切都是对象,从而提高语言的表现。基元存储在调用栈中,需要更少的存储空间并且操作起来更便宜。另一方面,对象存储在程序堆中,这需要复杂的内存管理和更多的存储空间。

由于性能原因,Java的字符串被设计为处于基元和类之间。

例如

String s1 = "Hello";    // String literal 
String s2 = "Hello";    // String literal 
String s3 = s1;     // same reference 
String s4 = new String("Hello"); // String object 
String s5 = new String("Hello"); // String object 

enter image description here

**注:***字符串文本*被存储在一个公共游泳池。这有助于共享具有相同内容的字符串的存储以节省存储空间。 String通过新操作员分配的对象存储在heap中,并且相同内容不存在共享存储。

+66

请注意,“公共池”通常是堆的一部分。 –

+3

@JoachimSauer是的..没有什么好处:)在补充说明。感谢记住。 –

+2

因此编写String s1 =“Hello”会更快;比String s2 = new String(“Hello”);? – user2097804

5

双引号内的文本创建一个立体的String对象。

String myString = "Some text"; 

上面的代码使用双引号创建String对象。

17

字符串在JLS中得到特殊处理:它是文字存在的两种非原始类型之一(另一种是Class*

the JLS

字符串文字是类的一个实例的引用字符串`[...]。

*好,这里还有the "null type"与它的“空文本” null,但大多数人并不认为“零式”的正确类型。

+1

我也没有意识到“null type”是Java中的一种适当类型。它非常有用的信息,你应该增加字体大小。 –

+1

@GrijeshChauhan:好吧,“空类型”只是一个漂亮的措辞,允许任何'null'分配给任何引用类型变量。这不是一个有趣的类型,否则。 –

15

这是Java语言的一个特性。源代码中的字符串文字被给予特殊处理。

语言规范,here,简单地说,一个字符串文字是String

1

Java.lang.String不只是一个类。它是核心语言的一个组成部分。编译器有它的语法糖。例如,""就像是new String("")的缩写。当编写""时,编译器会将相同的字符串优化为相同的实例以节省空间。 "a" + 5 == "a5" ==> true

编译器具有很多东西的语法糖,包括不必在对象版本和它们的本机类型之间加框/加框,没有父指的是对象,默认构造函数,...

+5

''''不是'new String(“”)'的缩写。如果使用''“',首先要做的是在JVM的字符串池中查找匹配项,如果是,则返回该字符串。通过使用'new String(“”)',你总是会创建一个新的String,即使String本身已经存在于String池中(因为它不会被存储在String池中)。 – g00glen00b

+0

我更新了我的答案。人们是否利用这个优势,比如像使用Lisp符号类型的等价物那样使用字符串常量? – Sylwester

46

的Java把String作为一类特殊的, 可以以两种方式初始化

  1. 使用new关键字直接分配字面

    String a = "adsasdf"; 
    
  2. 与其它对象

    String a = new String("adsasdf"); 
    

你需要的时候你想与==迹象比较特别照顾:

String a = "asdf"; 
String b = "asdf"; 
System.out.println(a == b); // True 
System.out.println(a.equals(b)); // True 

String a = new String("asdf"); 
String b = new String("asdf"); 
System.out.println(a == b); // False 
System.out.println(a.equals(b)); // True 

这是因为在第一种情况下的对象A和B都保存在一种叫做literal pool,他们都在引用同一个对象,使他们两种方式都是平等的。

但在第二种情况下,a和b引用不同的对象,比如我们初始化任何其他对象时。因此与==运算符相比,它们不相等,而它们的值相同。

+3

非常好的答案,你表现出的差异。 –

+3

如此翔实.. – vusan

2

-字符串是Java中的一类。你说得对,所以我们可以始终使用new关键字进行初始化。

-但是,当我们这样做:

String s = "";

上面的语句是由编译标记是一个特殊String对象然后JVM加载的期间类(加载在初始化之前完成),看到这是什么被称为字符串文字,它存储在一个字符串文献l池

-所以字符串可使用new()并通过""方法来创建,但后者提供字面一个字符串,它停留在堆即使存在到字符串对象的参考,因为它有一个参考来自字符串文字池。

4

字符串经常用在编程语言中。由于java是面向对象的,字符串是一个对象。为了避免繁琐的新String(“someString”);语句每当你需要一个字符串对象时,java允许你通过使用字符串文字来创建一个字符串对象。

但是你应该记住字符串相等。 这里有一个简短的JUnit测试来演示我的意思。

@Test 
    public void stringTest() { 
     // a string literal and a string object created 
     // with the same literal are equal 
     assertEquals("string", new String("string")); 

     // two string literals are the same string object 
     assertSame("string", "string"); 

     // a string literal is not the same object instance 
     // as a string object created with the same string literal 
     assertFalse("string" == new String("string")); 

     // java's String.intern() method gives you the same 
     // string object reference for all strings that are equal. 
     assertSame("string", new String("string").intern()); 
    } 
+0

如果你只能用'new String(String src)'初始化一个字符串,那么你甚至不能给构造函数一个字符串文字。你必须初始化一个'char []',然后使用String(char [] src)'consructor来构造字符串,否则你必须从文件中读取字符串。 – AJMansfield

+0

这是不正确的。字符串文字只是源文件中由双引号引起的字符序列。 Java会使用这个文字自动创建一个字符串的实例。因此,一个字面值和一个字符串对象是相等的,但它们并不相同。 Java也可以用这种方式实现,你必须使用新的String(“”);实例化一个String对象,但这只会让我们的生活变得更加艰难。所以当你编写新的String(“一个字符串”)时,java会为字符串“字符串”创建一个String对象,并将这个字符串对象传递给新String的构造器。 –

2

只要提一下。字符串文字是对类String实例的引用,您可以这样编写代码:

 
"abc".getBytes(); 

"a:b:c".split(":"); 

"愛".codePointAt(0); 
2

Java对我们来说有两个步骤。

String str = "hello"; 

相当于

char data[] = {'h', 'e', 'l' , 'l', 'o'}; 
String str = new String(data); 

像[.NET] [1]得到了类似的事情。

String(Char[]) constructor 

确实

String(char[] value) 

添加引用: -

+0

@Peter莫特森感谢编辑 – user1769790

+2

您所描述的过程是不是Java的实际作用:正如其他人已经说过,'“你好”'是一个字符串文字,将被编译器放入常量池中,请参阅[JLS§ 3.10.5](http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5)和[JVMS§5.1](http:// docs。 oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.1)。 – siegi