Java 泛型通配符为“和”;扩展;及;超级";
我正在从事一个需要将服务添加到组件的项目。Java 泛型通配符为“和”;扩展;及;超级";,java,generics,wildcard,Java,Generics,Wildcard,我正在从事一个需要将服务添加到组件的项目。服务类是一个没有任何方法的接口。以下是我的服务如何工作的示例: public interface Service { } public interface CarWash extends Service { void washCar(Car car); } public interface CarRepair extends Service { void repairCar(Car car); } 现在有许多这些服务的实现。一个类可以实现多
服务
类是一个没有任何方法的接口。以下是我的服务如何工作的示例:
public interface Service { }
public interface CarWash extends Service {
void washCar(Car car);
}
public interface CarRepair extends Service {
void repairCar(Car car);
}
现在有许多这些服务的实现。一个类可以实现多个服务,如车库类:
public class Garage implements CarWash, CarRepair {
@Override
public void washCar(Car car) { /* .. */ }
@Override
public void repairCar(Car car) { /* .. */ }
}
向组件添加服务时,我不想在所有任务中都使用该服务,但例如,仅将车库用于洗车(CarWash
),而不用于修理汽车(CarRepair
)。因此,我将任务指定为类,如下所示:
void addService(Service service, Class<? extends Service> task);
我正在寻找一种方法来指定服务
需要实现(扩展)任务
,而任务
正在扩展服务
接口,如下(不编译):
addService(T service,Class我认为void addService(S service,Class 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.
}
}
公共静态类Foo{
公共接口服务{}
公共接口洗车扩展服务{
使洗车无效();
}
公共接口CarRepair扩展服务{
无效维修车();
}
静态void addService(S服务,类clazz){}
公共静态void main(字符串[]args){
addService(null,CarWash.class);//很好。
addService(null,Object.class);//编译错误。
}
}
(我添加了一些static,并从方法签名中删除了Car
,因为我没有要编译的定义)这也可以,具体取决于您如何使用服务的类型:
<T extends Service> void addService(T service, Class<T> task)
我唯一的问题是varargs强制所有数组元素都属于同一类型,因此我无法编写addService(null,CarWash.class,CarRepair.class);
对于Java泛型来说,这实际上是一个困难的问题。(C++可以用它来实现,这是Java不太可能获得的特性。)
因此,用Java解决这个问题的一种方法是运行时验证,例如:
<T extends Service> void addService(
T service, Class<? super T> tasks...) {
for(Class<? super T> task : tasks)
if(!Service.class.isAssignableFrom(tasks))
throw new IllegalArgumentException();
}
void addService(
T service,Class关于:void addService(S service,Class clazz);
?有效,非常感谢!我唯一的问题是varargs强制所有数组元素为相同类型,因此我无法编写addService(null,CarWash.Class,CarRepair.Class)
。现在您没有询问varargs…这听起来像是一种情况,您无论如何都不想使用数组,应该更喜欢使用Iterable,例如静态void addService(S service,IterableI同意。我认为可以将其作为一个参数,并多次调用该方法来为多个任务添加服务,就像您在回答中所做的那样。
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.
}
}
<T extends Service> void addService(T service, Class<T> task)
addService(new Garage(), CarWash.class); // OK, Garage is a CarWash
<T extends Service> void addService(
T service, Class<? super T> tasks...) {
for(Class<? super T> task : tasks)
if(!Service.class.isAssignableFrom(tasks))
throw new IllegalArgumentException();
}