Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java:literal strings

Tags:

java

string

class A { 

String s4 = "abc";

 static public void main(String[]args ) {

        String s1 = "abc";
        String s2 = "abc";
        String s3 = new String("abc");
        A o = new A();
        String s5 = new String("def");

        System.out.println("s1==s2 : " + (s1==s2));
        System.out.println("s1==s1.intern : " + (s1==s1.intern()));
        System.out.println("s1==s3 : " + (s1==s3));
        System.out.println("s1.intern==s3.intern : " + (s1.intern()==s3.intern()));
        System.out.println("s1==s4 : " + (s1==o.s4));
 }
} 

The output:

s1==s2 : true
s1==s1.intern : true
s1==s3 : false
s1.intern==s3.intern : true
s1==s4 : true

My questions:

1.What happens for "String s1 = "abc"? I guess the String object is added to the pool in class String as an interned string? Where is it placed on? The "permanent generation" or just the heap(as the data member of the String Class instance)?

2.What happens for "String s2 = "abc"? I guess no any object is created.But does this mean that the Java Intepreter needs to search all the interned strings? will this cause any performance issue?

3.Seems String s3 = new String("abc") does not use interned string.Why?

4.Will String s5 = new String("def") create any new interned string?

like image 556
Don Li Avatar asked May 20 '12 09:05

Don Li


People also ask

Why are strings literals in Java?

Why Java uses the concept of String literal? To make Java more memory efficient (because no new objects are created if it exists already in the string constant pool).

What is literal string?

A "string literal" is a sequence of characters from the source character set enclosed in double quotation marks (" "). String literals are used to represent a sequence of characters which, taken together, form a null-terminated string.

What is literal and non literal string in Java?

String literal in Java is a set of characters that is created by enclosing them inside a pair of double quotes. In contrast, String Object is a Java is a set of characters that is created using the new() operator.


3 Answers

  1. The compiler creates a String object for "abc" in the constant pool, and generates a reference to it in the bytecode for the assignment statement.

  2. See (1). No searching; no performance issue.

  3. This creates a new String object at runtime, because that is what the 'new' operator does: create new objects.

  4. Yes, for "def", but because of (3) a new String is also created at runtime.

The String objects at 3-4 are not interned.

like image 169
user207421 Avatar answered Oct 14 '22 01:10

user207421


1.What happens for "String s1 = "abc"?

At compile time a representation of the literal is written to the "constant pool" part of the classfile for the class that contains this code.

When the class is loaded, the representation of the string literal in the classfile's constant pool is read, and a new String object is created from it. This string is then interned, and the reference to the interned string is then "embedded" in the code.

At runtime, the reference to the previously created / interned String is assigned to s1. (No string creation or interning happens when this statement is executed.)

I guess the String object is added to the pool in class String as an interned string?

Yes. But not when the code is executed.

Where is it placed on? The "permanent generation" or just the heap(as the data member of the String Class instance)?

It is stored in the permgen region of the heap. (The String class has no static fields. The JVM's string pool is implemented in native code.)

2.What happens for "String s2 = "abc"?

Nothing happens at load time. When the compiler created the classfile, it reused the same constant pool entry for the literal that was used for the first use of the literal. So the String reference uses by this statement is the same one as is used by the previous statement.

I guess no any object is created.

Correct.

But does this mean that the Java Intepreter needs to search all the interned strings? will this cause any performance issue?

No, and No. The Java interpretter (or JIT compiled code) uses the same reference as was created / embedded for the previous statement.

3.Seems String s3 = new String("abc") does not use interned string.Why?

It is more complicated than that. The constructor call uses the interned string, and then creates a new String, and copies the characters of the interned string to the new String's representation. The newly created string is assigned to s3.

Why? Because new is specified as always creating a new object (see JLS), and the String constructor is specified as copying the characters.

4.Will String s5 = new String("def") create any new interned string?

A new interned string is created at load time (for "def"), and then a new String object is created at runtime which is a copy of the interned string. (See previous text for more details.)

like image 38
Stephen C Avatar answered Oct 14 '22 02:10

Stephen C


See this answer on SO. Also see this wikipedia article on String Interning.

like image 2
Jeshurun Avatar answered Oct 14 '22 02:10

Jeshurun