I was going through this question Is there a way to override class variables in Java? The first comment with 36 upvotes was:
If you ever see a
p
It's more a stylistic thing than a direct problem. It suggests that you haven't properly thought through what is going on with the class.
Think about what static
means:
This variable exists at class level, it does not exist separately for each instance and it does not have an independent existence in classes which extend me.
Think about what protected
means:
This variable can be seen by this class, classes in the same package and classes which extend me.
The two meanings are not exactly mutually exclusive but it is pretty close.
The only case I can see where you might use the two together is if you had an abstract class that was designed to be extended and the extending class could then modify the behavior using constants defined in the original. That sort of arrangement would most likely end up very messy though and indicates weakness in the design of the classes.
In most cases it would be better to have the constants as public since that just makes everything cleaner and allows the people sub-classing more flexibility. Quite apart from anything else in many cases composition is preferable to inheritance, while abstract classes force inheritance.
To see one example of how this could break things and to illustrate what I mean by the variable not having an independent existence try this example code:
public class Program {
public static void main (String[] args) throws java.lang.Exception {
System.out.println(new Test2().getTest());
Test.test = "changed";
System.out.println(new Test2().getTest());
}
}
abstract class Test {
protected static String test = "test";
}
class Test2 extends Test {
public String getTest() {
return test;
}
}
You will see the results:
test
changed
Try it yourself at: https://ideone.com/KM8u8O
The class Test2
is able to access the static member test
from Test
without needing to qualify the name - but it does not inherit or get its own copy. It is looking at the exact same object in memory.
It's frowned upon because it's contradictive.
Making a variable protected
implies it will be used within the package or it will be inherited within a subclass.
Making the variable static
makes it a member of the class, eliminating the intentions of inheriting it. This leaves only the intention of being used within a package, and we have package-private
for that (no modifier).
The only situation I could find this useful for is if you were declaring a class that should be used to launch the application (like JavaFX's Application#launch
, and only wanted to be able to launch from a subclass. If doing so, ensure the method is also final
to disallow hiding. But this is not "the norm", and was probably implemented to prevent adding more complexity by adding a new way to launch applications.
To see the access levels of each modifier, see this: The Java Tutorials - Controlling Access to Members of a Class