Java - Overriding return type of extended interface when return type uses generics for own method parameter types

A basic idea is now to change this generic return type from GenericType in Interface A into GenericType in Interface A1

This is not possible, because Java Generics are invariant. [1]

As you found out, you cannot have an interface declaring a method that returns GenericType<Object> and in a sub interface override the method to return GenericType<String>: The latter return type is not a subtype of the former. And for good reason!

You tried to

extend indirectly the same interface with different generic types. This is unfortunately not allowed.

There is no way this could possibly work: E.g. what should be the type of E in public E set(int index, E element) in a class that implemented both List<String> and List<Object>? Your subclassed interface would have to produce a similar hybrid: The return value of getAGenericType in the sub interface would have to implement both the GenericType<String> and the GenericType<Object> interface. And as we saw, this is impossible.

The compiler does not know what you are going to do with the type parameter in GenericType (although it theoretically could find out, it doesn't). If you had a variable of type GenericType<String> and assigned a GenericType<Object> to it, you may very well end up putting a Long instance where a String is expected, and get a ClassCastException where you won't expect one.

In the doSomethingWith method of your variable GenericType<? extends Object> aGenericType2 you can pass one thing: null. null is the only object reference that has a subtype of ? extends Object. The lower bound type of ? extends Object is the null type, which cannot be expressed in Java, and only implicitly exists as the type of the null reference.

[1] http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29#Java


I don't know if this is what you are expecting, but you can declare your interface something like:

public interface Interface <K extends Object> { ... } 

While your class might look like:

public class InterfaceImpl implements Interface<String> { ... }

@Override annotation:

When overriding a method, you might want to use the @Override annotation that instructs the compiler that you intend to override a method in the superclass. If, for some reason, the compiler detects that the method does not exist in one of the superclasses, it will generate an error.

With this annotation you cannot change return type of function.

If you want to override return type, just make interface A more abstract, add generic to this interface:

public interface InterfaceA<T> {
  public GenericType<T> getAGenericType();  
}

Sample about overriding a generic method in a generic class.