a.DOG is not an instance field of instance "a" but a static field. Therefore, all the compiler needs is the reference type. Instead of seeing "a.DOG" the compiler actually sees "Animals.DOG" because "a" is declared as an instance of Animals.
In the past it was even possible to do the following:
This behaviour has been removed in Java 1.4 though, and now it will throw an ArrayIndexOutOfBoundsException. Sun could change the JVM so that your code will throw a NullPointerException, but they probably won't because too many programmers have bad code like this.
And yes, bad code it is. You shouldn't try to access a static member using an instance reference. It will not use polymorphism so there is no use. The following will all print the same:
The private method should simply be changed:
That's not (completely) Sun's fault. Sure, they can change the JVM to throw a NullPointerException in these cases. Sure, they can remove classes, methods and fields from the API that have been deprecated for at least 5 years. But the problem is that Java has so much backward compatibility. Code written for Java 1.1 will in most cases still run in Java 6. If these language constructs are then taken out of the JVM or API then code that uses them will no longer run. For projects that are still maintained that's ok, but what about legacy code? A lot of companies still have old code that they do not update because the simply do not have to.
That said, they did remove the "incorrect array index is no error" construct for static fields. I guess they assumed that that construct was not used as much as using a null reference to access static fields.
Joined: Dec 22, 2009
The insight into the process that Sun probably used to classify what to retain and what to change was good. Thank you.