16
public class Test {

    private static final String str1 = new String("en");
    private static Test instance = initInstance();

    private static final String str2 = new String("en");
    private static final String str3 = "en";

    private Test() {
    }

    public static void main(String[] args) {
    }

    private static Test initInstance() {
        instance = new Test();
        System.out.println(str1 + ',' + str2 + ',' + str3);
        return instance;
    }
}

Theoretically with statics everywhere it should result in "en,en,en".

Result: "en,null,en"

Expected: "en,null,null" (since i discovered statics order actually matters)

Could somebody explain this? What is so different about "en" and new String("en")?

1
  • +1 because I had no idea you could initialize inline like that... Commented Jul 20, 2012 at 18:01

3 Answers 3

19

Yes. At the time you invoke the method, str2 is not yet initialized (fields are initialized in order of declaration) and str3 is a compile-time constant.

Compile-time constants are inlined by the compiler in the class file. new String("..") is not a constant, because it uses a constructor.

String constants are defined by the string literal: "", and they are placed in a string pool in the jvm instance so that they are reused. Contrary to that, using new String(..) creates a new instance, and so should be avoided.

Sign up to request clarification or add additional context in comments.

1 Comment

Should inlined be changed to interned?
11

This happens because class variables initialized with constants are initialized first, and only then are more complex initializers (like your expressions using new String()) done (those are then done in source order). See JLS §8.3.2.1:

8.3.2.1. Initializers for Class Variables

[...]

At run-time, static fields that are final and that are initialized with constant expressions (§15.28) are initialized first (§12.4.2). This also applies to such fields in interfaces (§9.3.1). These fields are "constants" that will never be observed to have their default initial values (§4.12.5), even by devious programs (§13.4.9).

Comments

4

1. Its because str3 = "en" is a String literal in literal pool, and str1 = new String("en") is a String object at the String object pool.

2. As "en" is a literal, ie "constant" it will be initialized at the beginning.

3. Its also called as Constant Folding, pre calculation of the constants to execute faster.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.