Difference between string object and string literal

JavaStringString Literals

Java Problem Overview


What is the difference between

String str = new String("abc");

and

String str = "abc";

Java Solutions


Solution 1 - Java

When you use a string literal the string can be interned, but when you use new String("...") you get a new string object.

In this example both string literals refer the same object:

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

Here, 2 different objects are created and they have different references:

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

In general, you should use the string literal notation when possible. It is easier to read and it gives the compiler a chance to optimize your code.

Solution 2 - Java

A String literal is a Java language concept. This is a String literal:

"a String literal"

A String object is an individual instance of the java.lang.String class.

String s1 = "abcde";
String s2 = new String("abcde");
String s3 = "abcde";

All are valid, but have a slight difference. s1 will refer to an interned String object. This means, that the character sequence "abcde" will be stored at a central place, and whenever the same literal "abcde" is used again, the JVM will not create a new String object but use the reference of the cached String.

s2 is guranteed to be a new String object, so in this case we have:

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

Solution 3 - Java

The long answer is available here, so I'll give you the short one.

When you do this:

String str = "abc";

You are calling the intern() method on String. This method references an internal pool of String objects. If the String you called intern() on already resides in the pool, then a reference to that String is assigned to str. If not, then the new String is placed in the pool, and a reference to it is then assigned to str.

Given the following code:

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

When you check for object identity by doing == (you are literally asking: do these two references point to the same object?), you get true.

However, you don't need to intern() Strings. You can force the creation on a new Object on the Heap by doing this:

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

In this instance, str and str2 are references to different Objects, neither of which have been interned, so that when you test for Object identity using ==, you will get false.

In terms of good coding practice: do not use == to check for String equality, use .equals() instead.

Solution 4 - Java

As Strings are immutable, when you do:

String a = "xyz"

while creating the string, the JVM searches in the pool of strings if there already exists a string value "xyz", if so 'a' will simply be a reference of that string and no new String object is created.

But if you say:

String a = new String("xyz")

you force JVM to create a new String reference, even if "xyz" is in its pool.

For more information read this.

Solution 5 - Java

"abc" is a literal String.

In Java, these literal strings are pooled internally and the same String instance of "abc" is used where ever you have that string literal declared in your code. So "abc" == "abc" will always be true as they are both the same String instance.

Using the String.intern() method you can add any string you like to the internally pooled strings, these will be kept in memory until java exits.

On the other hand, using new String("abc") will create a new string object in memory, which is logically the same as the "abc" literal. "abc" == new String("abc") will always be false, as although they are logically equal they refer to different instances.

Wrapping a String constructor around a string literal is of no value, it just needlessly uses more memory than it needs to.

Solution 6 - Java

String is a class in Java different from other programming languages. So as for every class the object declaration and initialization is

String st1 = new String();

or

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

Here, st1, st2 and st3 are different objects.

That is:

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

Because st1, st2, st3 are referencing 3 different objects, and == checks for the equality in memory location, hence the result.

But:

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

Here .equals() method checks for the content, and the content of st1 = "", st2 = "hello" and st3 = "hello". Hence the result.

And in the case of the String declaration

String st = "hello";

Here, intern() method of String class is called, and checks if "hello" is in intern pool, and if not, it is added to intern pool, and if "hello" exist in intern pool, then st will point to the memory of the existing "hello".

So in case of:

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

Here:

st3 == st4 // true

Because st3 and st4 pointing to same memory address.

Also:

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

Solution 7 - Java

In the first case, there are two objects created.

In the second case, it's just one.

Although both ways str is referring to "abc".

Solution 8 - Java

Some disassembly is always interesting...

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

Solution 9 - Java

In addition to the answers already posted, also see this excellent article on javaranch.

Solution 10 - Java

According to String class documentation they are equivalent.

Documentation for String(String original) also says that: Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable.

Look for other responses, because it seems that Java documentation is misleading :(

Solution 11 - Java

The following are some comparisons:

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

When intern() is called the reference is changed.

Solution 12 - Java

There is a subtle differences between String object and string literal.

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

In this simple case, "abc" will go in the pool and s will refer to it.

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

In this case, because we used the new keyword, Java will create a new String object in normal (non-pool) memory, and s will refer to it. In addition, the literal "abc" will be placed in the pool.

Solution 13 - Java

String s = new String("FFFF") creates 2 objects: "FFFF" string and String object, which point to "FFFF" string, so it is like pointer to pointer (reference to reference, I am not keen with terminology).

It is said you should never use new String("FFFF")

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser395617View Question on Stackoverflow
Solution 1 - JavaMark ByersView Answer on Stackoverflow
Solution 2 - JavaAndreas DolkView Answer on Stackoverflow
Solution 3 - JavaJonView Answer on Stackoverflow
Solution 4 - JavaAwinView Answer on Stackoverflow
Solution 5 - JavakrockView Answer on Stackoverflow
Solution 6 - JavaNCAView Answer on Stackoverflow
Solution 7 - Javasushil bharwaniView Answer on Stackoverflow
Solution 8 - JavaaioobeView Answer on Stackoverflow
Solution 9 - JavaZakiView Answer on Stackoverflow
Solution 10 - JavaMichał NiklasView Answer on Stackoverflow
Solution 11 - JavaJavaFreakView Answer on Stackoverflow
Solution 12 - JavaKamalView Answer on Stackoverflow
Solution 13 - JavaforetView Answer on Stackoverflow