我试图对不同的服务实现进行通用处理,并且不断收到“由于原始类型而导致未经检查的呼叫”错误。
我尝试了几种实现方式,但不太了解这里的问题。
我有以下模型:
public abstract class Fruit {
public List<String> vitamins;
public String originCountry;
// getters and setters omitted
}
具体实现如下:
public class Kiwi extends Fruit {
}
public class Pineapple extends Fruit {
}
我有以下界面:
public interface FruitCheckService<T extends Fruit> {
List<String> compareVitaminsFromDifferentCountries(T firstFruit, T secondFruit);
Class<T> getImplementation();
}
具有上述两个模型的实现:
@Service
public class KiwiCheckServiceImpl implements FruitCheckService<Kiwi> {
@Override
public List<String> compareVitaminsFromDifferentCountries(Kiwi firstFruit, Kiwi secondFruit) {
// some implementation
return new ArrayList<>();
}
@Override
public Class<Kiwi> getImplementation() {
return Kiwi.class;
}
}
还有菠萝:
@Service
public class PineappleCheckServiceImpl implements FruitCheckService<Pineapple> {
@Override
public List<String> compareVitaminsFromDifferentCountries(Pineapple firstFruit, Pineapple secondFruit) {
// some implementation
return new ArrayList<>();
}
@Override
public Class<Pineapple> getImplementation() {
return Pineapple.class;
}
}
我有以下用不同的bean操作的类:
@Service
public class FruitServices {
private Map<Class, FruitCheckService> beansMap;
@Autowired
public FruitServices(List<FruitCheckService> fruitCheckServices) {
beansMap = new HashMap<>();
fruitCheckServices
.forEach(
fruitCheckService -> {
Class implementation = fruitCheckService.getImplementation();
beansMap.put(implementation, fruitCheckService);
}
);
}
public FruitCheckService getFruitCheckService(Class clazz) {
return beansMap.get(clazz);
}
}
最后,这是我称之为的服务:
@Component
public class BusinessService {
@Autowired
private FruitServices fruitServices;
public void compareVitamins(Fruit one, Fruit two) {
Class<? extends Fruit> aClass = one.getClass();
FruitCheckService fruitCheckService = fruitServices.getFruitCheckService(aClass);
List<String> result = fruitCheckService.compareVitaminsFromDifferentCountries(one, two);
}
}
如何正确使用fruitCheckService而不以原始类型'exercise2.service.FruitCheckService'的成员的身份收到“未经检查的对'compareVitaminsFromDifferentCountries(T,T)的调用”?
答案 0 :(得分:1)
问题是您在服务定义中使用了原始类型Class
。要解决此问题,可以使用bounded wildcard type ?
,如下所示:
class FruitServices {
private Map<Class<? extends Fruit>, FruitCheckService<? extends Fruit>> beansMap;
public FruitServices(List<FruitCheckService<? extends Fruit>> fruitCheckServices) {
beansMap = new HashMap<>();
fruitCheckServices
.forEach(
fruitCheckService -> {
Class<? extends Fruit> implementation = fruitCheckService.getImplementation();
beansMap.put(implementation, fruitCheckService);
}
);
}
public FruitCheckService<? extends Fruit> getFruitCheckService(Class<? extends Fruit> clazz) {
return beansMap.get(clazz);
}
}
对于类BusinessService
,事情将变得更加棘手。首先,必须使compareVitamins
为通用方法,以确保两个水果都属于同一类型。但是即使那样,我仍然认为您无法避免getFruitCheckService
的结果导致的未经检查的转换,因为FruitServices
必须处理针对不同类型水果的服务,因此您无法精确返回值getFruitCheckService
的类型参数。
class BusinessService {
private FruitServices fruitServices;
public <T extends Fruit> void compareVitamins(T one, T two) {
@SuppressWarnings("unchecked")
FruitCheckService<T> fruitCheckService =
(FruitCheckService<T>) fruitServices.getFruitCheckService(one.getClass());
List<String> result = fruitCheckService.compareVitaminsFromDifferentCountries(one, two);
}
}