yegor256
yegor256

Reputation: 105063

How to make return type generic in interface?

There are three Java 1.6 interfaces inheriting one from another:

interface First<T extends First<T>> {
  T me();
}
interface Second<T extends Second<T>> extends First<T> {
}
interface Third<T extends Third<T>> extends Second<T> {
  void foo();
}

Now I'm expecting this one to work, but no:

// somewhere later
public void bar(Third t) {
  t.me().foo();
}

Compiler says that t.me() is of type Second. What am I doing wrong?

Upvotes: 0

Views: 220

Answers (2)

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272497

Try this instead:

public <T extends Third<T>> void bar(Third<T> t) {
    t.me().foo();
}

Upvotes: 1

Tom Anderson
Tom Anderson

Reputation: 47183

The problem is that you haven't supplied a type parameter in the declaration of t, which makes it a raw type. All reasoning around generics is thus out of play. Because me() is declared as returning a type T in a class parameterised with T extends First, its raw type is First, and that's what the compiler will treat it as being even when it came from a Third.

If you were to supply a parameter to t - of any value! - the compiler would be able to use the rules about generics, and could work out that me() returns a Third. For example, writing some class Foo as Oli suggests would do it, as would binding it to ?.

If you have an instance of Third as a variable of raw type, assign it to a variable of type Third. That is legal, never unchecked, and will get you where i think you need to be.

Upvotes: 1

Related Questions