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