views:

64

answers:

4

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.

+5  A: 

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.

BalusC
A: 

Only one instance of a String is created for a string literal. These are stored in the "intern pool" of the String class. So, given these String initializations:

String copy = new String("x"); String alias = copy.intern();

The statements copy != "x" and alias == "x" are both true.

In this case, it would be much more readable if you just had a field.

erickson
A: 

foo will be instantiated each time your function is called because it is a local variable inside a method. The fact that this particular method is static is irrelevant. foo being final also has no effect on when it is instantiated, it just means that foo cannot change after the initial assignment.

Make it a private static class variable to ensure it is only instantiated once.

jlewis42
A: 

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.

Suresh Kumar