Consider the following interface in Java:
public interface I {
public final String KEY = "a";
}
And the following class:
public class A implements I {
public String KEY = "b";
public String getKey() {
return KEY;
}
}
Why is it possible for class A to come along and override interface I's final constant?
Try for yourself:
A a = new A();
String s = a.getKey(); // returns "b"!!!
You should not access your constant in this way, use the static reference instead:
It looks like your class is simply hiding the variable, not overwriting it:
This will print "B", and "A", as you found. You can even assign to it, as the A.KEY variable is not defined as final.
But -
Despite the fact that you are shadowing the variable it's quite interesting to know that you can change final fields in java as you can read here:
You are hiding it, it's a feature of "Scope". Any time you are in a smaller scope, you can redefine all the variables you like and the outer scope variables will be "Shadowed"
By the way, you can scope it again if you like:
Now KEY will return "c";
Edited because the original sucked upon re-reading.
As a design consideration,
The static methods always returns the parent key.
Just like Jom has noticed. The design of static methods using re-defined interface members could be a heavy problem. In general, try to avoid use the same name for the constant.
Static fields and methods are attached to the class/interface declaring them (though interfaces cannot declare static methods as they are wholly abstract classes which need to be implemented).
So, if you have an interface with a public static (vartype) (varname), that field is attached to that interface.
If you have a class implement that interface, the compiler trick transforms (this.)varname into InterfaceName.varname. But, if your class redefines varname, a new constant named varname is attached to your class, and the compiler knows to now translate (this.)varname into NewClass.varname. The same applies for methods: if the new class does not re-define the method, (this.)methodName is translated into SuperClass.methodName, otherwise, (this.)methodName is translated into CurrentClass.methodName.
This is why you will encounter the warning "x field/method should be accessed in a static way". The compiler is telling you that, although it may use the trick, it would prefer that you used ClassName.method/fieldName, because it is more explicit for readability purposes.