Why do these two code examples produce different outputs?

Example 1:

class Animal { public static void saySomething() { System.out.print(" Gurrr!"); } } class Cow extends Animal { public static void saySomething() { System.out.print(" Moo!"); } public static void main(String [] args) { Animal [] animals = {new Animal(), new Cow()}; for( Animal a : animals) { a.saySomething(); } new Cow().saySomething(); } } 

Exit:

  Gurrr! Gurrr! Moo! 

Example 2:

  class Animal { public void saySomething() { System.out.print(" Gurrr!"); } } class Cow extends Animal { public void saySomething() { System.out.print(" Moo!"); } public static void main(String [] args) { Animal [] animals = {new Animal(), new Cow()}; for( Animal a : animals) { a.saySomething(); } new Cow().saySomething(); } } 

Output:

  Gurrr! Moo! Moo! 

I just don't understand why make saySomething non-static calls a second call to saySomething, which calls the Cow version instead of the Animal version. I realized that Gurrr! Moo! Moo! Gurrr! Moo! Moo! will be the way out anyway.

+7
java static
source share
5 answers

static methods are bound to their class at compile time and cannot be used polymorphically. When you declare a "static" method for Animal, it is always bound to the Animal class and cannot be overridden. Static methods are bound to a Class object, not to an instance of a class.

Regular methods are bound at runtime, so the JVM can look at your call at “saySomething” and try to determine if you are subclassing Animal, and if so, you have overridden the saySomething() method. Regular methods are tied to an instance of the object, not to the class itself.

That’s why you weren’t able to do this:

 class Animal { public abstract static void saySomething(); } 

Since "static" means "compile-time bound", it never makes sense for something to be static and abstract.

+1
source share

When you call saySomething() animal, the actual type of animal is not taken into account because saySomething() is static.

 Animal cow = new Cow(); cow.saySomething(); 

coincides with

 Animal.saySomething(); 

JLS Example:

When the target link is computed and then discarded because the call mode is static, this link is not checked to determine if it is null:

 class Test { static void mountain() { System.out.println("Monadnock"); } static Test favorite(){ System.out.print("Mount "); return null; } public static void main(String[] args) { favorite().mountain(); } 

}

which prints:
Mount Monadnock
Here, favorites returns null, but a NullPointerException is thrown.


Resources:

In the same topic:

  • Java Static Confusion
+7
source share

You cannot override static methods with the same signature in subclasses, just hide them.

For class methods, the runtime system calls the method defined at the compile time of the reference on which the method is called. For example, the runtime system calls a method defined in the type of the reference runtime on which the method is called.

http://life.csu.edu.au/java-tut/java/javaOO/override.html

+3
source share

Some of the famous overriding "PITFALLS"

  • static methods cannot be overridden
  • private methods cannot be overridden

This explains the conclusion.

+3
source share

Static methods are bound to the class, and not to the "instance" of the object. Because you mean "Animal" and call the static saySomething () method. He will always call Animal if you don’t mean the cow.

+1
source share

All Articles