3

I have generic class with generic method

class Foo<T> {
    public <E> E execute() {
        return null;
    }
}

Could someone explain to me why this:

class Bar extends Foo {
    public <E> E execute() {
        return null;
    }
}

produces error

execute() in Bar clashes with execute() in Foo; both methods have the same erasure, yet neither overrides the other

whereas this is ok

class Bar extends Foo<Object> {
    public <E> E execute() {
        return null;
    }
}
  • 5
    A *raw type* has no generic methods, hence, when extending `Foo`, you are inheriting the erased method `public Object execute()`. See [What is a raw type and why shouldn't we use it?](https://stackoverflow.com/q/2770321/2711488) – Holger Nov 28 '18 at 13:45
  • Thanks for the fast reply! – Matej Petrigač Nov 28 '18 at 14:27

1 Answers1

1

In the first example you use the raw type of Foo, so Foo's method signature is public Object execute(). This clashes with the generic version in Bar. This is actually easily reproducible without inheritance like so:

class Foo
{
    public <E> E execute() { return null; }
    public Object execute() { return null; }
}

In the second example you are not using the raw type of Foo so the signatures of the execute methods are an exact match. In this case it's just a simple method override. As such, you should probably annotate it.

class Bar extends Foo<Object> {
    @Override
    public <E> E execute() {
        return null;
    }
}
Michael
  • 41,989
  • 11
  • 82
  • 128