为泛型分配默认值

发布于 2025-01-03 02:35:16 字数 2211 浏览 1 评论 0原文

我通过反射调用一个方法,它的返回类型是通用的。我不希望返回值为 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;
    }
}

I'm calling a method by reflection, and its return type is generic. I don't want the return value to be null, so I in that case I want to assign a default value of that generic type.

That is, after calling the method by reflection, I'd like to execute something like this:

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";
    } 
}

But, of course, if 'resultNotNull == null', we can't call 'resultNotNull.getClass()' without getting an exception.

Any ideas on how to assign a default value depending on the generic type?

The whole code would be something like this:

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;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心不设防 2025-01-10 02:35:16

您可以使用 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);
}

You can use 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);
}
为你拒绝所有暧昧 2025-01-10 02:35:16

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

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

Why your T could not implements some interface or extend some base class? Then you could call some static default method from T which return default value for given class T. Pros? It will encapsulate your switch code just to right class.

Of course, without any interfaces, all your possible T class could just have some method like getDefaultValue().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文