158

If String is a class just like any other, how can it be initialized using double quotes?

Graham Borland
  • 60,055
  • 21
  • 138
  • 179
splitgames
  • 1,669
  • 3
  • 13
  • 14
  • 26
    String is a VIP class. `" "` is already a String! – johnchen902 Jul 05 '13 at 12:46
  • 2
    No special meaning. I just meant Very Important. That is, `java.lang.String` have special treatment of the Java Language. – johnchen902 Jul 05 '13 at 12:49
  • 16
    Who says that string is "a class like any other"? It is a very special class, unlike any other. Since your supposition is false, the question is not really answerable. – Eric Lippert Jul 05 '13 at 15:02
  • 6
    Just because supposition is false, it does not mean question is not answerable. And the correct answer already has 197 votes. – Koray Tugay Apr 16 '14 at 12:00

10 Answers10

298

Java String is Special

The designers of Java decided to retain primitive types in an object-oriented language, instead of making everything an object, so as to improve the performance of the language. Primitives are stored in the call stack, which require less storage spaces and are cheaper to manipulate. On the other hand, objects are stored in the program heap, which require complex memory management and more storage spaces.

For performance reason, Java's String is designed to be in between a primitive and a class.

For example

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

Note: String literals are stored in a common pool. This facilitates the sharing of storage for strings with the same contents to conserve storage. String objects allocated via the new operator are stored in the heap, and there is no sharing of storage for the same contents.

Naman
  • 27,789
  • 26
  • 218
  • 353
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
  • 77
    Note that the "common pool" is *typically* part of the heap. – Joachim Sauer Jul 05 '13 at 13:31
  • 3
    @JoachimSauer Yes..with little benefits :) added that in note.Thanks for remembering. – Suresh Atta Jul 05 '13 at 13:39
  • 2
    So is it faster to write String s1 = "Hello"; than String s2 = new String("Hello");? – user2097804 Jul 05 '13 at 13:50
  • 29
    I'd add that in your example s1 == s2 == s3 but s4 != s5 – Alfredo Osorio Jul 05 '13 at 14:01
  • 2
    Is the `common pool` a real thing in the VMs runtime or is it a collection of string objects at compile time that actually initializes one string and make every one after that an reference. Eg. we could have simulated th ecompilers behaviour with s4 and s5 if we defined s5 `String s5 = s4;`? – Sylwester Jul 06 '13 at 18:26
  • 2
    In contemporay Sun/Oracle VMs, the "common pool" is not typically part of the main heap; it is part of PermGen. This can matter if you call `intern()` on a bunch of Strings; they go in to the same pool as literals. PermGen is smaller than the heap, managed by separate options, and causes more severe problems if you run out of it. Either way, it's an actual mechanism in the Sun/Oracle JVM runtime & class definitions; see http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html and http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5. – Andrew Janke Jul 07 '13 at 12:21
  • 8
    @AndrewJanke on recent hotspot jvm (7), the string pool is not in perm gen and from Java 8 there is no perm gen any more... – assylias Aug 31 '13 at 06:14
  • 1
    @assylias Thankyou for updating,I'l surely update my post after I gone through that.Thanks again for the update. – Suresh Atta Aug 31 '13 at 06:17
  • I'm not sure about `s3==s2==s1`. Why does the `intern()` method exist when 2 same strings may actually be stored in different memory locations. Yes, s1==s2, but not necessarily s3. – Menelaos Oct 24 '14 at 12:20
  • I don’t think that it makes sense to say “*Java's String is designed to be in between a primitive and a class*”. The `String` class is definitely a class and it’s not even special, just immutable. The description of the pool is nice, but not an answer to the question why we can specify a string using double quotes. The actual answer is, because the language designers said so. Syntactical support for certain object types doesn’t require a pool, not even immutability, e.g. `int[] array = { 1, 2, 3};` or `Supplier s = this::toString;` or `Double d = 1.1;`… – Holger Oct 25 '19 at 09:12
50

Java treats String as a special class, you can initialize in both ways

  1. Directly assigning literal

    String a = "adsasdf";
    
  2. As other Objects using new keyword

    String a = new String("adsasdf");
    

You need to take special care when you wants to compare with == sign:

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

That is because in first case the objects a and b are kept in something called literal pool and they both are referencing same object so they are equal in both ways.

But in second case a and b references different objects like when we initialize any other objects. so they are unequal when compared with == operator whereas they are equal in values.

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
chetan
  • 2,876
  • 1
  • 14
  • 15
18

String gets special treatment in the JLS: it's one of the two non-primitive types for which literals exist (the other is Class) *.

From the JLS:

A string literal is a reference to an instance of class `String [...].

* well, there's also the "null type" with it's "null literal" null, but most people don't think of the "null type" as a proper type.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • 1
    I was also not aware of that "null type" is a proper type in Java. Its very helpful information, you should increase font size. – Grijesh Chauhan Jul 10 '13 at 05:55
  • 1
    @GrijeshChauhan: well, the "null type" is just nifty wording to allow any `null` to be assigned to any reference type variable. It's not an interesting type, otherwise. – Joachim Sauer Jul 10 '13 at 06:09
15

It's a feature of the Java language. String literals in the source code is given special treatment.

The language spec, here, simply says that a string literal is of String type

nos
  • 223,662
  • 58
  • 417
  • 506
5

Text inside double quotes creates a literal String object.

String myString = "Some text";

The code above creates a String object, using double quotes.

Nova Entropy
  • 5,727
  • 1
  • 19
  • 32
4

Strings are very often used in a programming language. Since java is object oriented a string is an object. To avoid the cumbersome new String("someString"); statement everytime you need a string object java allows you to just create a string object by using the string literal.

But you should keep in mind the string equality. Here a short JUnit test to demonstrate what I mean.

    @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());
    }
René Link
  • 48,224
  • 13
  • 108
  • 140
  • If you could only initialize a string with `new String(String src)`, then you wouldn't even be able to give the constructor a string literal. You would have to initialize a `char []`, and then use the `String(char [] src)` consructor to construct the string, or you would have to read the string from a file. – AJMansfield Jul 05 '13 at 13:48
  • That is not correct. A string literal is only a character sequence in a source file sourounded by double quotes. Java automatically creates an instance of a string using this literal. Therfore a literal and a String object are equal, but they are not the same. Java could have also be implemented in this way that you must use new String(" "); to instantiate a String object, but this would only make our life more hard. So when you write new String("a string") java creates a String object for the literal "a string" and passes this string object to the construtor of new String. – René Link Jul 17 '13 at 09:52
2

- String is a class in Java. You are right about it, so we can always initialize with the new keyword.

- But when we do something like:

String s = "";

The above statement is marked by the compiler to be a special String object and then JVM during loading of the class (loading is done before initialization), sees this what is known as a string literal, which is stored in a string literal pool.

- So a String can be created using new() and by the "" method, but the latter provides a string literal which stays in the heap even when there is no reference to that string object, because it has a reference from the string literal pool.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75
2

Just to mention. A a string literal is a reference to an instance of class String you can write code like this:

 "abc".getBytes();

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

 "愛".codePointAt(0);
mkdev
  • 972
  • 9
  • 12
2

Java does a two step process for us.

String str = "hello";

is equivalent to

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

Like [.NET][1] got a similar thing.

String(Char[]) constructor

does

String(char[] value)

Adding references:-

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
user1769790
  • 1,183
  • 3
  • 11
  • 23
  • 3
    The process you describe is not what Java actually does: As others have already stated, `"hello"` is a string literal and will be put into the constant pool by the compiler, see [JLS §3.10.5](http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5) and [JVMS §5.1](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.1). – siegi Jul 10 '13 at 22:43
1

Java.lang.String is not just a class. It's an integral part of the core language. The compiler has syntactic sugar for it. For example, "" is like an abbreviation for new String(""). When written "" the compiler optimizes identical strings to the same instance to save space. "a" + 5 == "a5" ==> true

The compiler has syntactic sugar for a lot of stuff, including not having to box/unbox between object versions and their native types, no parent means Object, default constructor, ...

Sylwester
  • 47,942
  • 4
  • 47
  • 79
  • 5
    `""` is not an abbreviation for `new String("")`. If you use `""`, the first thing that will be done is to look for matches in the String pool of the JVM and if that's true, it will return that String. By using `new String("")`, you will always create a new String, even if the String itself already exists in the String pool (because it will not be stored in the String pool). – g00glen00b Jul 05 '13 at 13:02
  • I updated my answer. Do people use this to their advantage, like using string constants like a equivalent to the Lisp symbol type? – Sylwester Jul 06 '13 at 18:14