Accessing a static variable via an object reference in Java

Why can we access a static variable via an object reference in Java, like the code below?

public class Static {
    private static String x = "Static variable";

    public String getX() {
        return this.x;                 // Case #1
    }

    public static void main(String[] args) {
        Static member = new Static();
        System.out.println(member.x);  // Case #2
    }   
}

Generally, public variables can be accessed by everybody, and private variables can only be accessed from within the current instance of the class. In your example you're allowed to access the x variable from the main method, because that method is within the Static class.

If you're wondering why you're allowed to access it from another instance of Static class than the one you're currently in (which generally isn't allowed for private variables), it's simply because static variables don't exist on a per-instance basis, but on a per class basis. This means that the same static variable of A can be accessed from all instances of A.

If this wasn't the case, nobody would be able to access the private static variable at all, since it doesn't belong to one instance, but them all.


The reason that it is allowed is that the JLS says it is. The specific sections that allows this are JLS 6.5.6.2 (for the member.x cases) and JLS 15.11.1 (in both cases). The latter says:

If the field is static:

  • If the field is a non-blank final field, then the result is the value of the specified class variable in the class or interface that is the type of the Primary expression.

  • If the field is not final, or is a blank final and the field access occurs in a class variable initializer (§8.3.2) or static initializer (§8.7), then the result is a variable, namely, the specified class variable in the class that is the type of the Primary expression.


Why are these allowed by the JLS?

Frankly, I don't know. I can't think of any good reasons to allow them.

Either way, using a reference or this to access a static variable is a bad idea because most programmers are likely to be mislead into thinking that you are using an instance field. That is a strong reason to not use this feature of Java.

In your first and second cases you should reference the variable as x or Static.x rather than member.x. (I prefer Static.x.)


It is not best practice to reference a static variable in that way.

However your question was why is it allowed? I would guess the answer is to that a developer can change an instance member (field or variable) to a static member without having to change all the references to that member.

This is especially true in multi-developer environments. Otherwise your code may fail to compile just because your partner changed some instance variables to static variables.