【问题标题】:Create new instance of T in Java在 Java 中创建 T 的新实例
【发布时间】:2011-04-19 01:10:48
【问题描述】:

在 C# 中,我们可以定义一个通用的class A<T> where T : new()。在这段代码中,我们可以用new T() 创建一个T 的实例。这是如何在 Java 中实现的?我读了一些文章说这是不可能的。

我使用 C# 中使用泛型的单例模式的原因如下:

public static class Singleton<T> where T : new()
{
    private static T instance;

    public static T Instance
    {
        get 
        {
            if (instance == null)
            {
                instance = SingletonCreater.Instance;
            }
            return instance;
        }
    }

    static class SingletonCreater
    {
        internal static readonly T Instance = new T();
    }
}

以及如何让这个方法更优雅?

【问题讨论】:

标签: c# java generics design-patterns


【解决方案1】:

不,您不能执行 new T(),因为您不知道 T 是否有无参数构造函数,并且由于 type erasure,T 的类型在运行时不存在。

要创建 T 的实例,您需要有类似的代码,

public <T> T create(Class<T> clazz) {
    try {
        //T must have a no arg constructor for this to work 
        return clazz.newInstance(); 
    } catch (InstantiationException e) {
        throw new IllegalStateException(e);
    } catch (IllegalAccessException e) {
        throw new IllegalStateException(e);
}

【讨论】:

  • 我明白了,所以我不能像我在 C# 中使用的那样实现,对吧?我们可以保持开放,看看是否还有其他想法。 :)
  • 在c#中,你怎么知道T有一个无参构造函数?
  • 在类定义中,我们有 where T : new() 这意味着这个 T 接受无参数构造函数:)
  • 无参数构造函数根本不是问题。类型擦除是。
  • 这部分我觉得MS的API更强大。
【解决方案2】:

是的,new T() 是不可能的,因为泛型是 Java 中的编译时特性。在运行期间,通用信息会丢失;因此,您将无法执行 new T(),因为 JVM 在运行时不知道 T 是什么。

您可能不走运使用您提到的使用 Java 的确切语法。

【讨论】:

    【解决方案3】:

    谢谢你们,总而言之,我们不能在 JAVA 中使用它。作为 Sbridges 的方式,在 C# 中,我们可以这样实现:

    static T Create(Type type)
    {
        return (T)Activator.CreateInstance(type);
    }
    

    甚至更简单:

    static T Create()
    {
        return Activator.CreateInstance<T>();
    }
    

    让你知道。

    【讨论】:

      猜你喜欢
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      • 2023-03-09
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多