泛型通配符"扩展"和"超级"

Fri*_*jof 9 java generics wildcard

我正在开发一个需要将服务添加到组件的项目.该Service班是没有任何方法的接口.以下是我的服务如何工作的示例:

public interface Service { }

public interface CarWash extends Service {
  void washCar(Car car);
}

public interface CarRepair extends Service {
  void repairCar(Car car);
}
Run Code Online (Sandbox Code Playgroud)

现在有许多这些服务的实现.单个类可以实现多个服务,如此车库类:

public class Garage implements CarWash, CarRepair {
  @Override
  public void washCar(Car car) { /* .. */ }
  @Override
  public void repairCar(Car car) { /* .. */ }
}
Run Code Online (Sandbox Code Playgroud)

向组件添加服务时,我不希望将该服务用于所有任务,但是例如Garage仅用于清洗汽车(CarWash)而不是用于修复它们(CarRepair).因此我将任务指定为类,如下所示:

void addService(Service service, Class<? extends Service> task);
Run Code Online (Sandbox Code Playgroud)

为了检查服务是否可以实际执行任务,我使用了泛型:

<T extends Service> addService(T service, Class<? super T> task);
Run Code Online (Sandbox Code Playgroud)

这很好但不检查提供的任务是否实际上是一个任务(一个实现的类Service),所以这将工作:

addService(myTask, Object.class);
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种方法来指定service需要实现(扩展)taskAND task扩展Service接口,就像这样(不编译):

<T extends Service> addService(T service, Class<? super T extends Service> task);
Run Code Online (Sandbox Code Playgroud)

And*_*ner 7

我认为这<T extends Service, S extends T> void addService(S service, Class<T> clazz)听起来符合您的标准:

public static class Foo {                                                                                   
  public interface Service { }                                                                          

  public interface CarWash extends Service {                                                            
    void washCar();                                                                                     
  }                                                                                                     

  public interface CarRepair extends Service {                                                          
    void repairCar();                                                                                   
  }                                                                                                     

  static <T extends Service, S extends T> void addService(S service, Class<T> clazz) {}                 

  public static void main(String[] args) {                                                              
    addService(null, CarWash.class);  // Fine.                                                                  
    addService(null, Object.class);   // Compilation error.                                                          
  }
}
Run Code Online (Sandbox Code Playgroud)

(我添加了一些静态并Car从方法签名中删除,因为我没有要编译的定义)