4

Suppose that you compile the following two classes. The first is meant to represent a client; the second, a library class.

public class Test{
    public static void main(String[] args) {
        System.out.println(Lib.FIRST + " " +
                           Lib.SECOND + " " +
                           Lib.THIRD);
    }
}


public class Lib{
    private Lib() { }; // Uninstantiable
    public static final String FIRST = "the";
    public static final String SECOND = null;
    public static final String THIRD = "set";
}

prints:

{the null set}

Now suppose that you modify the library class as follows and recompile it but not the client program:

public class Lib{
    private Lib() { }; // Uninstantiable
    public static final String FIRST = "physics";
    public static final String SECOND = "chemistry";
    public static final String THIRD = "biology";
}

prints:

{the chemistry set}

Why is the SECOND value changed but not the FIRST or THIRD?

Kevin K
  • 9,344
  • 3
  • 37
  • 62
Saurabh Kumar
  • 16,353
  • 49
  • 133
  • 212
  • Are there two "Lib" classes in the classpath? Did you restart the VM? What's your container? – JustinKSU Jan 17 '12 at 21:19
  • 2
    This is straight out of [Java Puzzlers](http://www.amazon.com/Java-Puzzlers-Traps-Pitfalls-Corner/dp/032133678X). Same string constants and everything. It's a great read if you want to understand the edgier cases of Java. – yshavit Jan 17 '12 at 21:19
  • 1
    This question is indeed plagiarized word for word from Java Puzzlers (puzzle #93). – Trevor Freeman Jan 20 '12 at 00:56

2 Answers2

7

That's a known caveat - constants are inlined when you compile your client program, so you have to recompile it as well.

See also:

Community
  • 1
  • 1
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 1
    (+1) Curious... didn't know that. – NPE Jan 17 '12 at 21:20
  • This is the accepted answer, but the response is not quite subtle enough. Specifically, null is not a constant expression, so it is not inlined, while the other two values are defined with a constant expression, so their values are inlined (which is why "the chemistry set" is what ends up being printed). – Trevor Freeman Jan 20 '12 at 01:07
3

The values (i.e. "the" and "set") are inlined while null is not inlined by the compiler while compilation. To avoid something like that you can use a accessor method.

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
  • Aren't accessor methods discouraged on using on static fields? Is this an exceptional case? – kosa Jan 17 '12 at 21:23
  • I was just saying if he wanted to avoid recompiling the client class itself. – Bhesh Gurung Jan 17 '12 at 21:24
  • No, I completely understand your intention, I am not saying you said something wrong, don't get me wrong. Just trying to see if you are aware of anything like there is an exception to use accessor in this. – kosa Jan 17 '12 at 21:28