Java:How to override this generic method?

喜欢而已 提交于 2019-12-03 07:19:32

For one method to override another it must apply to at least all valid parameters of the overridden method. Your base method is generic public <S extends T> List<S> save(Iterable<S> entities). So it will accept any type S that extends T. However your override is more restrictive because it will only accept collections of MyType, therefore it is not a valid override.

If you had your base class defined with T, and the method accepted just T, and the derived class locked down T to MyType you should be OK.

To give a better answer we need to see the class declarations for the two classes. I would suggest the following:

class MyClass<T>{
  public List<T> save(Iterable<T> entities);
}

class OtherClass extends MyClass<MyType>{
  public List<MyType> save(Iterable<MyType> entities);
}

EDIT:

If you don't have control over the base class (which it seems that you don't), you are stuck with the public <S extends MyType> List<S> save(Iterable<S> structures) signature. This is because the overridden method is genericized and so the overridding method must also be

Depends on how you have defined , the following works

public class TestGenerics2<T> {
    public <S extends T> List<S> save(Iterable<S> entities) {
        return new ArrayList<S>();
    }
}

public class TestGenerics3 extends TestGenerics2<Number> {
    @Override
    public <S extends Number> List<S> save(Iterable<S> entities) {
        return super.save(entities);
    }
}

Here's an example that compiles and that shows how to use it:

abstract class A<T> {
    abstract public <S extends T> List<S> save(Iterable<S> entities); 
}

class B extends A<List<Integer>> {

    @Override
    public <S extends List<Integer>> List<S> save(Iterable<S> entities) {
        return null;
    }
}

class C {
    public void useIt() {
        B b = new B();
        Iterable<ArrayList<Integer>> it = new ArrayList<ArrayList<Integer>>();
        b.save(it);
    }
}

Class A defines the method with the original signature. class B implements it and chooses List<Integer> for type parameter T. And finally, class C uses this method with an Iterable whore generic type is a subclass of List<Integer>.

Since

public <S extends T> List<S> save(Iterable<S> entities)

is given, your override must be for

public <S extends MyType> List<S> save(Iterable<S> structures)

and your implementation must respect that S might be a real subtype of MyType.

Your approach

public List<MyType> save(Iterable<MyType> structures)

is not a correct override:

  • since Java >=1.5 allows covariant return types and List<MyType> is a subtype of List<S extends MyType>, this is ok, but
  • Java only allows invariant parameter types, but Iterable<MyType> is a subtype of Iterable<S extends MyType>, hence your compiler error message.

My solution was to not override this at all but to create a service class that does the needed logic and leave repository untouched.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!