Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforcing return type for an class that implements an interface

Tags:

java

generics

How do I enforce that the method getFoo() in the implementing class, returns a list of the type of same implementing class.

public interface Bar{
     ....
     List<? extends Bar> getFoo(); 
}

Right now a class that implements Bar returns objects of any class that implements Bar. I want to make it stricter so that the class that implements Bar returns a List of objects of only its type in getFoo().

like image 462
I J Avatar asked Dec 06 '11 22:12

I J


2 Answers

Unfortunately this cannot be enforced by Java's type system.

You can get pretty close, though, by using:

public interface Bar<T extends Bar<T>> {
    List<T> getFoo();
}

And then your implementing classes can implement it like so:

public class SomeSpecificBar implements Bar<SomeSpecificBar> {
    // Compiler will enforce the type here
    @Override
    public List<SomeSpecificBar> getFoo() {
        // ...
    }
}

But nothing stops another class from doing this:

public class EvilBar implements Bar<SomeSpecificBar> {
    // The compiler's perfectly OK with this
    @Override
    public List<SomeSpecificBar> getFoo() {
        // ...
    }
}
like image 60
Daniel Pryden Avatar answered Sep 19 '22 23:09

Daniel Pryden


This is not possible in Java, but you might wonder what the use-case is to force this in the interface.

  • If you program against the interface (which you typically do, why else define the interface) the type wouldn't be known
  • If you program against a specific class, this thread already provided options on how you can implement that specific class to return a List<itself>. And since you program against that specific class, the compiler has access to that specific return type and knows about it
like image 23
Robin Avatar answered Sep 23 '22 23:09

Robin