假设您有EntityService<E>
,PersonService extends EntityService<Person>
,EmployeeService extends EntityService<Employee>
等。现在,假设您想创建一个SuperService
来聚合其他服务,这些服务将暴露给外部世界。由于泛型擦除,您无法编写SuperService extends PersonService, EmployeeService
,...如果不为每个服务编写特定的方法名称,有什么方法可以解决此问题?
public interface EntityService<E> {
E find(long id);
...
}
public interface PersonService extends EntityService<Person> { }
public interface EmployeeService extends EntityService<Employee> { }
// ERROR - SuperService can not be inherited with different types arguments
public interface SuperService extends PersonService, EmployeeService {}
当前,我正在SuperInterface
中编写特定的方法,这些方法在SuperInterface
实现中委派给基础服务。更具体地说,我很好奇,是否有一些注释处理器能够以最小的努力生成工作服务接口。
答案 0 :(得分:2)
您的意思是您想要此API的单入口,因此您的SuperService
。如果是这样,并且您不介意进行投射:
Map
这允许轻松存储服务,以及访问客户端所需实体的简单方法。
class SuperService {
private Map<Class<?>, EntityService<?>> services = ...;
public SuperService() { //populate the map somehow..
services.put(Person.class, new PersonServiceImpl());
services.put(Employee.class, new EmployeeServiceImpl());
}
public <E> E find(long id, Class<E> type) {
E service = services.get(type);
if(service == null)
throw new IllegalArgumentException("This API does not provide a service for the specified type.");
return (E) service.find(id);
}
}
这缺乏类型安全性。但是,您可以通过以下方式实现类型安全性:
instanceof
类型检查,或更糟糕的是:没有实际的类型检查)实施多次调度。 您现在可以将服务真正封装在您的API中:客户端仅知道实体,而不是用于获取该实体的实际服务。
客户端将使用以下方法:
SuperService service = new SuperService();
Person person = service.find(50, Person.class);
答案 1 :(得分:1)
以您尝试执行的方式是不可能的,对于从不同类型实现/继承的类型,对于这些类型存在多个具有相同签名的方法,实现/继承的类型只有该方法的一个版本,只要签名的返回类型不同,只要存在兼容性问题,就会在编译时提示。