Monday, April 6, 2009

Don't let Java final Strings trick you...

Imagine working on some production issue, where a UI message has to be changed (for it not being as per specifications ofcourse). So, here you are, faced with a very simple 'defect' (if you term it one ;) ).

All that needs to be done is to change the value of a final String variable somewhere in your Interface or concrete class that contains the same (example below), followed by shipping out the class file as a patch. A 2 mins job - and actually, does not even need a 'programmer' to make the change. So, you happily make the change, ship the file (without even bothering to test - due to sheer confidence or may be over-confidence as we find out why further...)

    public interface ConstStrings{

      String CONST_1 = "Java";
      String CONST_2 = "Blogger";

      Integer i1 = 9;
      Integer i2 = 20;


What happens when it reaches QA? Or worst still, the client? Boom, they still end up seeing the old incorrect message. What went wrong? Certainly, the message is changed in the class file and the patch is applied as expected!

Well, the problem turns out that, the UI class(example below) which refers to this class for getting the final constant variable has not been compiled! Now, try re-compiling the class that refers to the constant, and everything works as expected.

    public class ClassUsingConstants {
    private String str;
    private String str2;
    private Integer i1;
    private Integer i2;

    ClassUsingConstants() { // Constructor

      str = ConstStrings.CONST_1;
      str2 = ConstStrings.CONST_2;
      i1 = ConstStrings.i1;
      i2 = ConstStrings.i2;


    // Getters for the variables are here...


Behind the scenes, whenever you compile a class that refers to a String Constant (in another class or interface), the compiler creates the .class file with the constants embedded in it, instead of having a reference to the actual class that contains it. Hence, changing and re-compiling the referred class only is not sufficient, but what is actually required is re-compilation of all the classes that refer to the same.
However, a point to note here is that, this behaviour is exhibited only for Constant 'final' Strings and not for any other type of 'final' objects.

Hope this helps you, if it does, leave a comment :)

No comments:

Post a Comment