Name clash when overriding method of generic class

前端 未结 1 1600
时光说笑
时光说笑 2021-02-06 12:05

I\'m trying to understand the name clash error I get with the following code:

import java.util.*;
import javax.swing.*;

class Foo {
             


        
1条回答
  •  太阳男子
    2021-02-06 12:57

    Luiggi is right in the comments. This is a consequence of raw types.

    The supertype of a class may be a raw type. Member accesses for the class are treated as normal, and member accesses for the supertype are treated as for raw types. In the constructor of the class, calls to super are treated as method calls on a raw type.

    This applies when invoking a supertype method, but also when overriding one.

    Take for example, the following

    class Bar extends Foo {
        public Bar() {
            doSomething(1, new HashMap());
        }
    }
    

    You'll notice that it compiles, even though HashMap is not a type that is assignable to Map.

    The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.

    (Note that C in our case is Bar.)

    And the same thing happens when trying to override a method. When trying to override the Foo#doSomething(..) method, your Bar class is actually seeing it declared as

    public void doSomething(Number n, Map comps) {
    }
    

    In other words, every usage of type parameters is erased. So attempting to declare the method

    public void doSomething(Number n, Map comps) {
    }
    

    in the subtype Bar is actually an attempt at overloading, not overriding. And this fails because of type erasure. The proper override, which you can verify with @Override, is

    public void doSomething(Number n, Map comps) {
    }
    

    Further reading:

    • What is a raw type and why shouldn't we use it?

    0 讨论(0)
提交回复
热议问题