我有以下情况:
public abstract class BaseTask{...}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public interface TaskService<T extends BaseTask>{
void process(T task);
}
@Service @Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
}
@Service @Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{
}
public class ProcessingService{
@Autowired @Qualifier("taskServiceA")
private TaskService<TaskA> taskAService;
@Autowired @Qualifier("taskServiceB")
private TaskService<TaskB> taskBService;
public void process(Order o){
BaseTask task = o.getTask();
getTaskService(o).start(task);
}
private <T extends BaseTask> TaskService<T> getTaskService(Order o){
if("atype".equals(o.type)){
return (TaskService<T>) taskAService;
} else if("btype".equals(o.type)){
return (TaskService<T>) taskBService;
}
}
}
更新:我对这个问题进行了重新措辞,因为我得到的答案不是我想要的。
我的问题与getTaskService方法有关。
为什么我需要像这样强制转换返回值
返回(TaskService)taskAService;
是否有另一种无需执行强制转换即可实现getTaskService()方法的方法?
如果有人能为getTaskService
方法提供一些解释或更好的实现,我将不胜感激。
答案 0 :(得分:1)
怎么样?
Map<EnumTask, ? extends BaseTask> serviceMap;
而不是String。您对Tasks的最终调用可以不作任何检查
@Service
class ProcessingService {
@Autowired
private TaskServiceManager taskServiceManager;
public void process(Order o){
taskServiceManager.getServiceTask(o.type).start(task);
}
}
其他课程
enum ServiceEnum {
TaskA,
TaskB
}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public abstract class TaskService<T extends BaseTask>{
public TaskService(ServiceEnum serviceEnum, TaskServiceManager taskServiceManager) {
taskServiceManager.registerTask(serviceEnum, this);
}
void process(T task);
}
@Service @Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
@Autowired
public TaskA(TaskServiceManager taskServiceManager) {
super(ServiceEnum.TaskA, taskServiceManager);
}
}
@Service @Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{...}
@Service
class TaskServiceManager {
Map<ServiceEnum, ? extends TaskService> serviceMap;
public <T extends TaskService> void registerTask(ServiceEnum serviceName, T task) {
if(serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is already in the Map");
}
serviceMap.put(serviceName, task);
}
public <T extends TaskService> T getServiceTask(ServiceEnum serviceName) {
if(!serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is not Registered");
}
return serviceMap.get(serviceName);
}
}
答案 1 :(得分:1)
因为在任何使用该方法的位置都将解析类型T。以下语句是有效的:
TaskService<TaskA> s = getTaskService(o);
也是这样:
TaskService<TaskB> s = getTaskService(o);
因此在getTaskService方法中,您对T的了解不多。
正确的方法是:
private TaskService<? extends BaseTask> getTaskService(Order o) {
if ("atype".equals(o.type)) {
return taskAService;
} else if ("btype".equals(o.type)) {
return taskBService;
} else {
return null;
}
}
上面的分配必须变成:
TaskService<? extends BaseTask> s = getTaskService(o);