我想编写一个方法来检查参数为null的位置,如果是,则返回该类型的新对象。它看起来像:
public static <T> T checkNull(T obj) {
if (null == obj) return someHowCreateTheObjectWithTypeT();
else return obj;
}
经过一番挣扎和挖掘,我仍然无法找到实现这一目标的方法,它在java中是否可行?
我开始考虑反思。但是,当对象为null时,我无法获取Class实例,并且如果没有类型T的名称,则无法创建类...
更新
我考虑过将一个Class作为参数传递,但这不是最好的解决方案,如下面的答案所示:)
我的解决方案是使用defaultValue参数:
public static <T> T checkNull(T obj, T defaultValue) {
if (null == obj) return defaultValue;
return obj;
}
这比反射解决方案更快更安全,并且是相同的详细信息; 但是我必须为所有感兴趣的类型系统地指定一个DEFAULT_VALUE,这不是一件容易的事。
答案 0 :(得分:3)
通用信息仅为编译时,在运行时不可用。您必须将对象的Class作为提示传递,并且该类必须具有公共默认构造函数。 e.g。
public static T checkNull(Object o, Class<T> c) {
try {
return (o == null) ? c.newInstance() : o;
} catch (Exception e) {
return null;
}
}
答案 1 :(得分:3)
这是不可能的。为了使泛型以这种方式工作,它必须在编译时捕获它将被调用的类型。但是,null
没有类型,因此您无法找出T来实例化它。
现在,你可以解决这个问题,同时传递Class实例,但是你需要使用Reflection来进行一些相当强大的错误处理,以确保类型T是一个具体的类,并且有一个可以调用的公共无参数构造函数
答案 2 :(得分:2)
无法完成。您必须添加Class<T>
的其他参数,然后将其用于反射新的参数。类型T在编译过程中不存在。
答案 3 :(得分:1)
正如其他人所指出的那样,这是不可能做到的。但是,Guava提供的等价物与您发布的方法的默认值相同:
String foo = Objects.firstNonNull(someString, "default");
这与您的方法略有不同,因为如果两个参数都是firstNonNull
,NullPointerException
将抛出null
。
另一个选择是创建一个使用Guava的Supplier<T>
接口或类似的方法:
public static T firstNonNull(T first, Supplier<? extends T> defaultSupplier) {
return first != null ? first : Preconditions.checkNotNull(defaultSupplier.get());
}
然后,您可以使用Supplier
创建并返回一个新的默认实例,当且仅当第一个参数为null时。