2015-07-21 56 views
4

我需要改进的代码:变换一种类型到另

final String valueString = value.toString(); 

if (Path.class.isAssignableFrom(destinationType)) { 
    fixedValues.put(key, Paths.get(valueString)); 
} /* ... as above, for other types ... */ { 
} else { 
    fixedValues.put(key, valueString); 
} 

所以我决定实施一个变压器等,其类型X转换为另一种Y

我创造了这个接口

public interface Converter<S, D> { 
    D convert(final S source); 

    Class<D> getDestinationClass(); 
    Class<S> getSourceClass(); 
} 

所以当我需要实现一个转换我实现这个接口

public class StringToIntegerConverter implements Converter<String, Integer> { 
    @Override 
    public Integer convert(final String source) { 
    return Integer.parseInt(source); 
    } 

    @Override 
    public Class<Integer> getDestinationClass() { 
    return Integer.class; 
    } 

    @Override 
    public Class<String> getSourceClass() { 
    return String.class; 
    } 
} 

(字符串的例子 - >整数)

现在,转换我有另一个类Converters类型,其中包含一个表(两个键的番石榴表)存储所有转换器。

private final static ImmutableTable<Class<?>, Class<?>, Converter<?, ?>> converters; 

而且有方法convert

public <S, D> D convert(final Class<S> source, final Class<D> destination, final S value) { 
    return destination.cast(converters.get(source, destination).convert(source.cast(value))); 
} 

的错误是

incompatible types: S cannot be converted to capture#1 of ? 

source.cast(value)

,因为我把它们存储在地图?所以我很坚持。我不知道我该如何解决这个问题。我觉得这是不可能的,但我张贴,看看我错了。

我由Spring读this,但它是一个不同的方式

回答

3

你正在尝试实现是可能的:

@SuppressWarnings("unchecked") 
public <S, D> D convert(final Class<S> source, final Class<D> destination, final S value) { 
    final Converter<S, D> converter = (Converter) converters.get(source, destination); 

    return destination.cast(converter.convert(source.cast(value))); 
} 

然而,由于其性质的代码不能保证类型安全。你必须保证,Table中的3个元素是兼容的。

+0

哦,我明白你做了什么。我没有想到类似的东西。现在编译。现在我测试它,谢谢 – kMuller

+0

它会工作,但如果你弄糟了转换器表,那么你将得到运行时ClassCastExceptions。 – Crazyjavahacking

+0

然后就可以了,因为这意味着创建实现的程序员无法实现这些方法。因为instace和表充满了反射(读取getSourceClass/getDestinationClass) – kMuller