Java: literal strings

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)); } } 

Exit:

 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 assume that the String object is added to the pool in the String class as an interned string? Where is it located?" Permanent generation "or just a bunch (like an instance data element of a String Class)?

2. What happens for "String s2 = "abc" ? I think no object has been created. But does this mean that Java Intepreter needs to look for all interned strings? Will it cause any performance problem?

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

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

+6
source share
4 answers

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

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

When the class is loaded, the string literal representation in the classfile 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 run time, a reference to a previously created / interned string is assigned to s1 . (When executing this statement, no string or internment is created).

I assume that a String object is being added to the pool in the String class as an interned string?

Yes. But not when the code is executed.

Where is he located? "Permanent generation" or just a heap (as a data element of an instance of a String Class)?

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

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

Nothing happens at boot time. When the compiler created the cool file, it reused the same constant pool entry for the literal that was used for the first use of the literal. Thus, the String reference used by this statement is the same as the previous statement.

I think no object has been created.

Right.

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

No and no. The Java interpreter (or JIT-compiled code) uses the same links that were created / embedded for the previous statement.

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

It is harder 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 representation. A new line is assigned to s3 .

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

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

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

+3
source
  • The compiler creates a String object for "abc" in the constant pool and generates a reference to it in byte code for the assignment operator.

  • See (1). No search; no performance issues.

  • This creates a new String object at runtime because this is what the "new" operator does: create new objects.

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

3-4 String objects are not interned.

+5
source

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

+2
source

String s1 = "abc"; creates a new line and puts it.

String s2 = "abc"; drag the same object as for s1 from the internal pool. The JVM does this to improve performance. This is faster than creating a new line.

The call to new String() redundant, as it will return a new implicit String object. Does not retrieve it from the internal pool.

As Keyser says, == compares the matching of strings for an Object, returning true if they are the same object. When comparing the contents of a String, you should use .equals()

-1
source

Source: https://habr.com/ru/post/916188/


All Articles