Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a final String inside a private static method instantiate a new object when invoked?

Does a static final String inside a private static method instantiate a new object when invoked?

private static String Test() {
    final String foo = "string literal";
    return foo;
}

Or does the compiler know there is only a single, string literal, inside the method? Or should I make it a private static final class field? This has the effect of reducing readability by spreading the code around the class.

like image 489
Sarabjot Avatar asked Dec 21 '22 22:12

Sarabjot


2 Answers

You do not have to worry too much about String literals. String literals are given special treatment by the JVM to increase performance and decrease memory overhead. A string literal used anywhere in your code (local or otherwise) is pooled and reused by the JVM. This is done to cut down on the number of String objects created in the JVM. Each time your code creates a string literal, the JVM checks the string literal in the pool first. If the string already exists in the pool, a reference to the pooled instance is returned. If the string does not exist in the pool, a new String object is instantiated, then is placed in the pool. Java can make this optimization since strings are immutable and can be shared without fear of data corruption. However, this behaviour is true for String literals only and not objects created with the "new" keyword.

In summary, making a string literal a class variable (private static final class field) or keeping it as a local variable has the same effect.

like image 21
Suresh Kumar Avatar answered Mar 15 '23 23:03

Suresh Kumar


No, the particular string will be reused from the string literal pool. If it was for example:

final String foo = new String("string literal");

Then indeed a new one will be created everytime the method is invoked.

Here's an evidence:

public static void main(String[] args) throws Exception {
    String s1 = test1();
    String s2 = test1();
    System.out.println(s1 == s2); // true

    String s3 = test2();
    String s4 = test2();
    System.out.println(s3 == s4); // false
}

private static String test1() {
    final String foo = "string literal";
    return foo;
}

private static String test2() {
    final String foo = new String("string literal");
    return foo;
}

Note that the final modifier doesn't have any influence in this particular case. It only prohibits the variable from being reassigned.

like image 110
BalusC Avatar answered Mar 16 '23 01:03

BalusC