如何应用Java泛型来简化此代码

时间:2014-08-19 05:49:02

标签: java generics code-cleanup

我想知道是否有办法避免在下面的代码片段的第二行中进行投射。

另外,有没有办法通过在addIfMatters方法中使用convertToInteger,convertToBoolean等泛型来进一步简化代码?

public void process() {
    // How can I avoid the cast below?
    Boolean value = (Boolean) addIfMatters(target, source, true);  
    if (value){
        // I have some stuff to do here
    }
}

private Object addIfMatters(Map<String, Object> target, Source source, Object defaultValue) {
    Object value = null;
    if (needed(source)) {
    if (defaultValue instanceof Boolean) {
        value = convertToBoolean(source.getValue, defaultValue); // returns 'defaultValue' if value in source is null
    } else if (defaultValue instanceof Integer) {
        value = convertToInteger(source.getValue, defaultValue);
    } else if...
        // so on
    }
    target.put(source.getKey(), value);
}

5 个答案:

答案 0 :(得分:5)

基本上,您可以设置addIfMatters方法以返回与defaultValue相同的类型,例如......

public void process() {
    Map<String, Object> target = null;
    Source source = null;
    Boolean value = addIfMatters(target, source, true);  // How can I avoid the cast on this line?
    if (value) {
        // I have some stuff to do here
    }
}

private <T> T addIfMatters(Map<String, Object> target, Source source, T defaultValue) {
    T value = null;
    if (needed(source)) {
        if (defaultValue instanceof Boolean) {
            value = convertToBoolean(source.getValue, defaultValue); // returns 'defaultValue' if value in source is null
        } else if (defaultValue instanceof Integer) {
            value = convertToInteger(source.getValue, defaultValue);
        }
}
    return value;
}    

<强>更新

显着缺乏背景,这使得尝试提供合适的解决方案非常困难......

例如,如果可以应用Source来使用泛型类型,那么就不需要转换方法,并且可以确保source&#39之间存在连接; s值和默认值已应用,例如......

public void process() {
    Map<String, Object> target = null;
    Source<Boolean> source = null;
    Boolean value = addIfMatters(target, source, true);  // How can I avoid the cast on this line?
    if (value) {
        // I have some stuff to do here
    }
}

private <T> T addIfMatters(Map<String, Object> target, Source<T> source, T defaultValue) {
    T value = null;
    if (needed(source)) {
        value = source.getValue();
        if (value == null) {
            value = defaultValue;
        }
}
    return value;
}    

public boolean needed(Source source) {
    return true;
}

public class Source<T> {
    public T getValue() {
        return ...;
    }
}

答案 1 :(得分:0)

由于您已经在编译时知道这是一个布尔值,最简单的方法是创建多个包装器,每种类型一个。

private boolean addBooleanIfMatters(Map<String, Object> target, Source source, boolean defaultValue){
    return (Boolean) addIfMatters(target, source, defaultValue);
}

答案 2 :(得分:0)

您可以使用以下代码段来实现泛型。

private <T> T addIfMatters(Map<String, Object> target, Source source, T defaultValue) {
        T value = null;
        if (needed(source)) {
            if (defaultValue instanceof Boolean) {
                value = convertToBoolean(source.getValue(), defaultValue); // returns 'defaultValue' if value in source is null
            } else if (defaultValue instanceof Integer) {
                value = convertToInteger(source.getValue(), defaultValue);
            } else  {

            }
        }
        return value;
    }

答案 3 :(得分:0)

如果可能,最好的选择是做MadProgrammer建议并使Source通用。否则,我会像下面这样做。这假设convertBoolean等除了返回defaultValue或转换给定值之外什么都不做。

public <T> T addIfMatters(Map<String, Object> target, Source source, T defaultValue) {
    if (needed(source)) {
        Object o = source.getValue();
        if(o == null) {
            return defaultValue;
        }
        Class<?> targetClass = defaultValue.getClass();
        if(targetClass.isInstance(o)) {
            @SuppressWarnings("unchecked")
            T value = (T) o;
            return value;
        } else {
            throw new IllegalArgumentException("Types do not match");
        }
    } else {
        return null;
    }
}

答案 4 :(得分:0)

在Java中无法将字符串一般转换为任意类型。因此,对于不同类型的代码需要不同的重载,以及代码基本相同的泛型:

public void process() {
    Boolean value = addIfMatters(target, source, true);
    if (value){
        // I have some stuff to do here
    }
}

private Boolean addIfMatters(Map<String, Object> target, Source source, Boolean defaultValue) {
    return addInternal(target, source, Boolean.parseBoolean(source.getValue()), defaultValue);
}

private Integer addIfMatters(Map<String, Object> target, Source source, Integer defaultValue) {
    return addInternal(target, source, Integer.parseInt(source.getValue()), defaultValue);
}

private <T> T addInternal(Map<String, Object> target, Source source, T converted, T defaultValue) {
    if (needed(source)) {
        target.put(source.getValue(), converted);
        return converted;
    }
    return null;
}