为通用分配默认值

时间:2012-02-06 15:36:57

标签: java generics reflection default-value

我通过反射调用方法,其返回类型是通用的。我不希望返回值为null,所以在这种情况下,我想指定该泛型类型的默认值

也就是说,通过反射调用方法之后,我想执行这样的事情:

T resultNotNull = (T) reflectionMethodThatCanReturnNull.invoke(anObject);
// If it's null, let's assign something assignable.
if (resultNotNull == null) {
    if (resultNotNull.getClass().isAssignableFrom(Long.class)) {
        resultNotNull = (T) Long.valueOf(-1);
    } else if (resultNotNull.getClass().isAssignableFrom(String.class)) {
        resultNotNull = (T) "NOTHING";
    } 
}

但是,当然,如果'resultNotNull == null',我们不能在没有异常的情况下调用'resultNotNull.getClass()'。

有关如何根据泛型类型分配默认值的任何想法?

整个代码将是这样的:

public class ReflectionTest {
    public class Class1ok {
        public Long method () { return Long.valueOf(1); }
    }   
    public class Class1null {
        public Long method () { return null; } // It returns null
    }   
    public class Class2ok {
        public String method () { return "SOMETHING"; }
    }

    public static void main(String[] args) {
        ReflectionTest test = new ReflectionTest();

        Long notNullValue1 
            = test.methodReturnNotNull(Class1ok.class); // 1
        Long notNullValue2 
            = test.methodReturnNotNull(Class1null.class); // -1, not null
        String notNullValue3 
            = test.methodReturnNotNull(Class2ok.class); // "SOMETHING"
    }

    public <T> T methodReturnNotNull(Class theClass) {
        T resultNotNull = null;
        try {
            Object theObject = theClass.newInstance();
            Method methodThatCanReturnNull = theClass.getMethod("method");
            resultNotNull = (T) methodThatCanReturnNull.invoke(theObject);
        } catch (Exception e) {
            // Meh.
        }

        // If it's null, assign something assignable.
        if (resultNotNull == null) {
            if (resultNotNull.getClass().isAssignableFrom(Long.class)) {
                resultNotNull = (T) Long.valueOf(-1);
            } else if (resultNotNull.getClass().isAssignableFrom(String.class)) {
                resultNotNull = (T) "NOTHING";
            } 
        }
        return resultNotNull;
    }
}

2 个答案:

答案 0 :(得分:3)

您可以使用getReturnType();

private static final Map<Class, Object> replacementForNull = new HashMap<>();
static {
    replacementForNull.put(String.class, "NOTHING");
    replacementForNull.put(Long.class, 1L);
}


Method reflectionMethodThatCanReturnNull = ...
T resultNotNull = (T) reflectionMethodThatCanReturnNull.invoke(anObject);
// If it's null, let's assign something assignable.
if (resultNotNull == null) {
    Class returnType = reflectionMethodThatCanReturnNull.getReturnType();
    resultNotNull = replacementForNull.get(returnType);
}

答案 1 :(得分:0)

为什么你的T无法实现某些接口或扩展某些基类?然后,您可以从T调用一些静态默认方法,该方法返回给定类T的默认值。优点?它会将您的switch代码封装到正确的类中。

当然,没有任何接口,所有可能的T类都可能只有getDefaultValue()这样的方法。