简体   繁体   中英

Overriding in Java Generics

I have a generic method in abstract parent class which I want to override in the concrete child:

Parent class:

public abstract class AbstractParentDataAccess<S extends AbstractParentDataModel> 
{
   ...
  public void save(Collection<? extends S> collection) {...}
   ...
}

Child Class:

public class ConcreteDataAccess extends AbstractParentDataAccess<ConcreteDataModel> 
{
   ...
   // this does not compile
   @Override
   public void save(Collection<ConcreteDataModel> collection) {...}

   // this compiles but never gets called, the parent method is being called instead
   @Override
   public void save(Collection<? extends ConcreteDataModel> collection) {...}
   ...

}

ConcreteDataModel class inherits from AbstractParentDataModel:

public class ConcreteDataModel extends AbstractParentDataModel {...} 

Here is how I call the save method:

...
@Autowired
private ConcreteDataAccess concreteDataAccess;
....
List<ConcreteDataModel> dataList = DataService.getDataList();
concreteDataAccess.save(dataList);
...

So my question is:

Why:

  1. does the first method not compile?
  2. is parent method being called instead of child method in the second one and how to fix it?

It is impossible given what you have given us that the parent method is being called. You've typoed the methodname ( save ), or your calling code has an issue here.

Note that at the VM level, generics do not exist; both methods have the exact same JVM signature: save(Ljava/util/Collection;)V - even if the generics are wildly out of whack, it's the same method as far as the VM is concerned, and thus, the save in your child class overrides the one from parent.

List<ConcreteDataModel> does not compile here, because a Collection<? extends S> Collection<? extends S> allows more types than List<ConcreteDataModel> does. For example, this:

List<ConcreteDataModel> x = new ArrayList<SubTypeOfConcreteDataModel>();

does not compile, but this:

List<? extends ConcreteDataModel> x = new ArrayList<SubTypeOfConcreteDataModel>();

does. (Reason: You can call x.add(new ConcreteDataModel()); on a List<ConcreteDataModel> , putting something in your list of SubTypeOfConcreteDataModel that isn't a SubTypeOfConcreteDataModel. Note that you can't call .add() on a List<? extends WhateverYouWantToWriteHere> at all, unless you pass literally null .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM