Are all compile-time constants inlined?

Let's say I have a class like this:

class ApplicationDefs{
public static final String configOption1 = "some option";
public static final String configOption2 = "some other option";
public static final String configOption3 = "yet another option";
}

Many of the other classes in my application are using these options. Now, I want to change one of the options alone and deploy just the compiled class. But if these fields are in-lined in the consumer classes this becomes impossible right?

Is there any option to disable the in-lining of compile time constants?


You can use String.intern() to get the desired effect, but should comment your code, because not many people know about this. i.e.

public static final String configOption1 = "some option".intern();

This will prevent the compile time inline. Since it is referring to the exact same string that the compiler will place in the perm, you aren't creating anything extra.

As an alternative you could always do

public static final String configOption1 = "some option".toString();

however this will not use the compiled intern'd string, it will create a new one on the old gen. Not a huge big deal, and might be easier to read. Either way, since this is a bit odd you should comment the code to inform those maintaining it what you are doing.

Edit: Found another SO link that gives references to the JLS, for more information on this. When to use intern() on String literals


No, it's part of the JLS, I'm afraid. This is touched upon, briefly, in Java Puzzlers but I don't have my copy to hand.

I guess you might consider having these constants defined in a properties file, and have the class that loads them periodically.

Reference: http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#5313


No. You could replace them with a static method call, though, like:

class ApplicationDefs {

    public static String configOption1() { return "some option"; }

}

Granted, it’s not beautiful but it would fulfill your requirement. :)


Actually, if you remove the final keyword the constants stop being compile-time constants and then your configuration will work like you want.

However, it is strongly suggested that if this is indeed some sort of configuration you are trying to do, you should move to to a more manageable way than constants in some class file.


You can inhibit inlining by making your constant non-compile time constants...

For instance, null is not a compile time constant. Any expression involving a non-compile time constant is not a compile time constant, although javac may do constant folding within the compilation unit.

public static final String configOption1 = null!=null?"": "some option";