error in overriding generic collections in Java

前端 未结 5 1828
隐瞒了意图╮
隐瞒了意图╮ 2021-01-28 19:29

When I try to override a method that takes a List, I get the following compile error.

Multiple markers at this

5条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-28 19:38

    Basically your impression is incorrect and this is impossible. The JLS considers this specifically illegal.

    From 8.4.2:

    The signature of a method m1 is a subsignature of the signature of a method m2 if either:

    • m2 has the same signature as m1, or

    • the signature of m1 is the same as the erasure (§4.6) of the signature of m2.

    Two method signatures m1 and m2 are override-equivalent iff either m1 is a subsignature of m2 or m2 is a subsignature of m1.

    The emboldened bit is important because it doesn't say "the erasure of m1 is the same as the erasure of m2". What it actually does allow is this (and some more convoluted examples like it):

    class A {
        void process(List list) {}
    }
    class B extends A {
        @Override
        void process(List list) {} // |List| is erasure of List
    }
    

    Since the method signature of B.process is the erasure of A.process it is an override.

    According to 8.4.9, an example like in the OP could then be an overload because the signatures are not override-equivalent:

    If two methods of a class ... have the same name but signatures that are not override-equivalent, then the method name is said to be overloaded.

    Except that it's specifically a compile-time error (8.4.8.3):

    It is a compile-time error if a type declaration T has a member method m1 and there exists a method m2 declared in T or a supertype of T such that all of the following conditions hold:

    • m1 and m2 have the same name.

    • m2 is accessible from T.

    • The signature of m1 is not a subsignature (§8.4.2) of the signature of m2.

    • The signature of m1 or some method m1 overrides (directly or indirectly) has the same erasure as the signature of m2 or some method m2 overrides (directly or indirectly).

    These restrictions are necessary because generics are implemented via erasure. The rule above implies that methods declared in the same class with the same name must have different erasures. ...

提交回复
热议问题