简体   繁体   English

有没有办法定义检查null然后创建对象的泛型方法?

[英]Is there a way to define a generic method that checks for null and then create the object?

I'd like to write a method that checks where the argument is null, and if it is, returns a new object of that type. 我想编写一个方法来检查参数为null的位置,如果是,则返回该类型的新对象。 it looks like: 看起来像:

public static <T> T checkNull(T obj) {
    if (null == obj) return someHowCreateTheObjectWithTypeT();
    else return obj;
}

After some struggling and digging, I still can't get a way to achieve this, is it atually possible in java? 经过一番挣扎和挖掘,我仍然无法找到实现这一目标的方法,它在java中是否可能?

I thought about reflection at first. 起初我想过反思。 But I just can't get a Class instance when the object is null, and you can't create a Class without the type T's name... 但是,当对象为null时,我无法获取Class实例,并且如果没有类型T的名称,则无法创建Class ...

Update: 更新:

I thought about passing a Class as a parameter, but that's not the best solution, as the following answers shows :) 我想过将一个Class作为参数传递,但这不是最好的解决方案,如下面的答案所示:)

My currunt solution is to use a defaultValue parameter: 我的currunt解决方案是使用defaultValue参数:

public static <T> T checkNull(T obj, T defaultValue) {
    if (null == obj) return defaultValue;
    return obj;
}

Which is faster and safer than a reflection solution, and is the same verbose; 这比反射解决方案更快更安全,并且是相同的冗长; But then I have to systematically specify a DEFAULT_VALUE for all types of interest, which is not an easy work. 但是我必须为所有感兴趣的类型系统地指定一个DEFAULT_VALUE,这不是一件容易的事。

Generic information is compile time only and not available at runtime. 通用信息仅为编译时,在运行时不可用。 You'd have to pass the Class of the object in as a hint, and the class would have to have a public default constructor. 您必须将对象的Class作为提示传递,并且该类必须具有公共默认构造函数。 eg 例如

public static T checkNull(Object o, Class<T> c) {
  try {
    return (o == null) ? c.newInstance() : o;
  } catch (Exception e) {
    return null;
  }
}

This is not possible. 这是不可能的。 For generics to work in this manner, it has to capture at compile-time the type that it will be called with. 为了使泛型以这种方式工作,它必须在编译时捕获它将被调用的类型。 However, null has no type so you won't be able to figure out T to instantiate it. 但是, null没有类型,因此您无法找出T来实例化它。

Now, you may be able to work around this also passing in the Class instance, but you will need some rather robust error handling using Reflection to ensure that type T is a concrete class and has a public parameterless constructor that you can invoke. 现在,您可以解决此问题,同时传递Class实例,但是您需要使用Reflection来进行一些相当强大的错误处理,以确保类型T是一个具体的类,并且具有可以调用的公共无参数构造函数。

Cannot be done. 无法做到。 You must add an additional parameter of Class<T> , and then use it to reflectively new. 您必须添加Class<T>的其他参数,然后将其用于反射新的。 The type T does not survive the compilation process. 类型T在编译过程中不存在。

As others have pointed out, this can't be done. 正如其他人所指出的那样,这是不可能做到的。 However, Guava provides an equivalent to the default value you method you posted: 但是, Guava提供的等效于您发布的方法的默认值:

String foo = Objects.firstNonNull(someString, "default");

This differs slightly from your method in that firstNonNull will throw a NullPointerException if both arguments are null . 这与您的方法略有不同,因为如果两个参数都为null ,则firstNonNull将抛出NullPointerException

Another option would be to create a method that makes use of Guava's Supplier<T> interface or something similar: 另一个选择是创建一个使用Guava的Supplier<T>接口或类似方法的方法:

public static T firstNonNull(T first, Supplier<? extends T> defaultSupplier) {
  return first != null ? first : Preconditions.checkNotNull(defaultSupplier.get());
}

You could then use a Supplier that creates and returns a new default instance when and only when the first argument is null. 然后,您可以使用当且仅当第一个参数为null时创建并返回新默认实例的Supplier

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM