考虑到以下内容,我很难找到一种方法来做到这一点似乎没有错误
public interface IType {}
public interface IMode {}
public interface Factory<T extends IType> {
IMode get(T o);
Class<T> getIType();
}
我有上面的接口和一个关于类IType
和IMode
以及相应工厂的类的大型列表。
我需要能够从一个转换为另一个,例如,
public class A implements IType {}
public class One implements IMode {}
public class AToOne implements Factory<A> {
public IMode get(A o){
return new One();
}
public Class<A> getIType(){
return A.class;
}
}
鉴于这些类存在1对1的映射,即对于每个具体的IType
,只有一个具有相应工厂的具体IMode
,我如何将IType
的列表转换为IMode
的列表?
即
private List<Factory<? extends IType>> factoryList;
public List<IMode> getConversions(List<? extends IType> types){
???
}
我的第一次尝试并没有那么顺利,
//Fill this using the getIType() method from each factory
Map<Class<IType>, Factory<? extends IType>> factoryList = new HashMap<Class<IType>, Factory<? extends IType>>();
public List<IMode> getConversions(List<IType> types){
List<IMode> modes = new ArrayList<IMode>();
for(IType type : types){
//Derp
Factory<? extends IType> factory = factoryList.get(type.getClass());
//Error
factory.get(factory.getIType().cast(type));
}
}
错误:
The method get(capture#12-of ? extends IType) in the type
Factory<capture#12-of ? extends IType>
is not applicable for the arguments (capture#14-of ? extends IType)
答案 0 :(得分:2)
就像我在评论中提到的那样,您只需要使用通用帮助方法来访问地图,该地图执行从Factory<? extends IType>
到Factory<T>
的未经检查的强制转换,其中T
匹配传递的内容类型:
Map<Class<? extends IType>, Factory<? extends IType>> factoryList =
new HashMap<Class<? extends IType>, Factory<? extends IType>>();
private <T extends IType> IMode convert(T iType) {
//unchecked cast - implementation must guarantee map holds correct data
Factory<T> factory = (Factory<T>)factoryList.get(iType.getClass());
//then convert
return factory.get(iType);
}
您可以从循环中调用此辅助方法:
public List<IMode> getConversions(List<IType> types) {
List<IMode> modes = new ArrayList<IMode>(types.size());
for (IType type : types) {
IMode iMode = convert(type);
modes.add(iMode);
}
return modes;
}
答案 1 :(得分:1)
简单的解决方案如下:
interface IFoo {
}
interface IBar {
}
private static class Foo implements IFoo {
}
private static class Bar implements IBar {
}
interface IFoo2IBarConverter<B extends IBar, F extends IFoo> {
B convert(F foo);
}
private static class Foo2BarConverter implements IFoo2IBarConverter<Bar, Foo> {
public Bar convert(Foo foo) {
return new Bar();
}
}
private static class IFoo2IBarFactory {
private static HashMap<Class<? extends IFoo>, IFoo2IBarConverter<? extends IBar, ? extends IFoo>> converters = new HashMap<>();
static {
converters.put(Foo.class, new Foo2BarConverter());
}
public static<F extends IFoo, B extends IBar> B convert(F foo) {
// ugly unchecked cast here
IFoo2IBarConverter<B, F> converter = (IFoo2IBarConverter<B, F>) converters.get(foo.getClass());
return converter.convert(foo);
}
}
public static void main(String[] args) {
Foo foo = new Foo();
IBar bar = IFoo2IBarFactory.convert(foo);
}
您只需使用HashMap将特定类(IFoo
的子类型映射到某个转换器接口。转换器获取IFoo
实例并将其转换为IBar
..实际上转换为我们想要的特定类。可悲的是,我们在IFoo2IBarFactory.convert()
得到了一个丑陋的演员,我认为没有办法避免那个。至少它只是在一个本地化的位置,并且有正确的评论和SuppressWarning,你可以忍受它,我想