Присвоение значения по умолчанию универсальному - PullRequest
6 голосов
/ 06 февраля 2012

Я вызываю метод по отражению, а его тип возвращаемого значения является общимЯ не хочу, чтобы возвращаемое значение было нулевым, поэтому я в этом случае хочу назначить значение по умолчанию этого универсального типа .

То есть после вызывая метод с помощью отражения, я хотел бы выполнить что-то вроде этого:

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 ]

3 голосов
/ 06 февраля 2012

Вы можете использовать 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);
}
0 голосов
/ 06 февраля 2012

Почему ваш T не может реализовать какой-либо интерфейс или расширить базовый класс?Затем вы можете вызвать некоторый статический метод по умолчанию из T, который возвращает значение по умолчанию для данного класса T.Плюсы?Он будет инкапсулировать ваш switch код только в нужный класс.

Конечно, без каких-либо интерфейсов, весь ваш возможный класс T может иметь какой-то метод, например getDefaultValue().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...