Why, if the static method is not associated with polymorphism (last binding), I see an error that the static method cannot be overridden

consider the following code:

class A{ public static void m(Number n){ System.out.println("Number A"); }; } class B extends A{ public static int m(Number n){ System.out.println("Number B"); return 1; }; } 

exit:

java: m (java.lang.Number) in inheritanceTest.B cannot override m (java.lang.Number) in inheritanceTest.A return type int is not compatible with void

I know that static methods are not included in polymorphism, so I conclude that overriding is impossible for my code. This compiler message is strange to me.

As I understand it, redefinition is part of polymorphism. I'm getting ready for scjp and I'm afraid to make a mistake in a familiar question.

Please clarify this problem.

expected behavior for me - overload error message

P.S1.

I read the popular question of static overrides and I did not find the answer (

P.S2. According to Pshemo's answer:

this code:

 class Foo{ public static void m(Number n){ System.out.println("Number A"); }; public static int m(Number n){ System.out.println("Number B"); return 1; }; } 

outputs:

 error: method m(Number) is already defined in class Foo public static int m(Number n){ ^ 1 error 

For me, these situations are the same. But the compiler error is different - strange.

+8
java override inheritance polymorphism static
source share
3 answers

JLS §8.4.8.3 (Java 8) says:

If the declaration of method d 1 with return type R 1 overrides or hides the declaration of another method d 2 with return type R 2 , then d 1 must be replaced with the return type (§8.4.5) for d 2 , or a compile-time error occurs.

The same rule applies to both instance methods and static methods, because it says "overrides or hides". Basically, if you have a method with the same name and with the same parameters, it overrides if it is an instance method, but hides (an inherited method) if it is a class (static) method. And in both cases, the return type must either be one or obey the rules of covariance.

Since this is the same rule, most likely there is only one place in the compiler code that checks this rule, and if this rule is violated, you get an error message, which, I am sure, is much more common. The compiler really needs to check if it should say “override” or “hide”, but it looks like they slipped. Getting the correct error message is usually not the highest priority for the compiler authors - not in comparison with the fact that the code that should be compiled does this and works correctly, but the code that should not be compiled is not. Therefore, I believe that this is a drawback, but very minor.

+7
source share

Even if static methods cannot be overridden, they are still inherited, so what you are trying to do will lead to a situation similar to

 class Foo{ public static void m(Number n){ System.out.println("Number A"); }; public static int m(Number n){ System.out.println("Number B"); return 1; }; } 

which is wrong, because you cannot have two methods with the same signature, but with different types of returned data. The reason this was forbidden is pretty simple ... Let's say we have methods:

  • Foo method(){ return new Foo(); }
  • Bar method(){ return new Bar(); }

and you would like to call them like

 System.out.println(method()); 

Should the result be Foo or Bar? The compiler will not be able to solve.

To prevent such situations, the compiler forbids overriding / hiding methods with the same signature by changing the types of returned data. The only exception is when you change the type of the return value to a more detailed one, for example

 class X{ List<String> m(){...} } class Y extends X{ LinkedList<String> m(){...} } 

So it seems that override not the best word here. The correct word should be hide , since static methods can be hidden, not overridden. But since the same rules check whether we can override / hide the method, the same error message is displayed in case of any problems that may be misleading.

+7
source share

I think that using the 'override' compiler error is misleading, this is not applicable.

language specification says:

If the declaration of method d1 with the return type R1 overrides or hides the declaration of another method d2 with the return type of R2, then d1 must be the return type that is replaced for d2, or a compile-time error occurs.

Here, your method B hides the declaration of Am:

If the class declares a static method m, then it is said that the declaration m hides some method m ', where the signature m is the submission (§8.4.2) of the signature m', in the superclasses and superinterfaces of the class that would otherwise be accessible to code in the classroom.

If your class B does not have a method m, then you can call Bm and it will call m defined on A.

The presence of Bm hides the version of m. Since you can call the static method defined in the superclass, but refer to a subclass that sets some expectations regarding the method, which is violated using a different return type.

It hides, not overrides, because if you have Bm defined, you can still call Am and get a version of this superclass method. With its redefinition, the type of runtime that decides what is called and what it is called does not matter.

+2
source share

All Articles