有没有办法定义一个通用方法来检查 null 然后创建对象?

发布于 2024-09-30 11:51:18 字数 652 浏览 3 评论 0原文

我想编写一个方法来检查参数是否为空,如果是,则返回该类型的新对象。看起来像:

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

经过一番努力和挖掘,我仍然找不到实现这一目标的方法,这在java中实际上可能吗?

我一开始就想到了反思。但当对象为 null 时,我无法获取 Class 实例,并且如果没有类型 T 的名称,则无法创建 Class...

更新:

我考虑过将 Class 作为参数传递,但这不是最好的解决方案,如以下答案所示:)

我当前的解决方案是使用 defaultValue 参数:

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

这比反射解决方案更快、更安全,并且同样冗长; 但随后我必须系统地为所有类型的兴趣指定一个 DEFAULT_VALUE,这不是一件容易的工作。

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. 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?

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...

Update:

I thought about passing a Class as a parameter, but that's not the best solution, as the following answers shows :)

My currunt solution is to use a defaultValue parameter:

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.

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

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

发布评论

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

评论(4

捶死心动 2024-10-07 11:51:18

这是不可能的。为了让泛型以这种方式工作,它必须在编译时捕获它将被调用的类型。但是,null 没有类型,因此您无法找出 T 来实例化它。

现在,您也许可以解决这个问题,同时传入 Class 实例,但是您将需要使用反射进行一些相当强大的错误处理,以确保类型 T 是一个具体类,并且具有一个可以调用的公共无参数构造函数。

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.

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.

咋地 2024-10-07 11:51:18

通用信息仅在编译时存在,在运行时不可用。您必须传递对象的类作为提示,并且该类必须有一个公共默认构造函数。例如

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

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. e.g.

public static T checkNull(Object o, Class<T> c) {
  try {
    return (o == null) ? c.newInstance() : o;
  } catch (Exception e) {
    return null;
  }
}
花想c 2024-10-07 11:51:18

做不到。您必须添加一个额外的参数Class,然后使用它进行反射式new。类型 T 在编译过程中无法存活。

Cannot be done. You must add an additional parameter of Class<T>, and then use it to reflectively new. The type T does not survive the compilation process.

秋日私语 2024-10-07 11:51:18

正如其他人指出的那样,这是不可能做到的。但是,Guava 提供了与您发布的方法的默认值等效的值:

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

这略有不同在您的方法中,如果两个参数都为 null,则 firstNonNull 将抛出 NullPointerException

另一种选择是创建一个使用 Guava 的 Supplier 接口或类似接口的方法:

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

然后您可以使用 Supplier 创建并返回一个新的默认实例当且仅当第一个参数为空时。

As others have pointed out, this can't be done. However, Guava provides an equivalent to the default value you method you posted:

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

This differs slightly from your method in that firstNonNull will throw a NullPointerException if both arguments are null.

Another option would be to create a method that makes use of Guava's Supplier<T> interface or something similar:

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.

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