代码之家  ›  专栏  ›  技术社区  ›  Dan TheCodeJunkie

如何用Java编写泛型方法

  •  3
  • Dan TheCodeJunkie  · 技术社区  · 16 年前

    在C#中,我会这样做

        public static T Resolve<T>()
        {
            return (T) new object();
        }
    

    Java中的等价物是什么?

    4 回复  |  直到 16 年前
        1
  •  11
  •   jason    13 年前

    首先,你的例子是错误的;它将抛出一个 InvalidCastException 除非 typeof(T) == typeof(object) . 您可以通过添加 constraint :

    public static T Resolve<T>() where T : new() {
        return new T();
    }
    

    public static <T> T Resolve() {
        return (T) new T();
    }
    

    T 在宣言中:一个是 T <T> 它参数化了方法,第二个是返回类型 T .

    不幸的是,上述内容在Java中不起作用。由于Java泛型的实现方式,运行时类型信息 不可用,因此上面给出了编译时错误。现在,您可以像这样处理此约束:

    public static <T> T Resolve(Class<T> c) {
        return c.newInstance();
    }
    

    请注意需要传入 T.class runtime type token . 这是处理这种情况的惯用方法。

        2
  •  2
  •   nd.    16 年前

    正如其他评论者所指出的那样,您也可以使用Java来实现这一点——尽可能在运行时创建强制转换异常:

    @SuppressWarnings("unchecked")
    public static <T> T resolve() {
      return (T) new Object();
    }
    

    除非你使用 @SuppressWarnings 类型消除 开始运行时,您将收到编译器警告。例外情况也会发生在其他地方:无论您在何处尝试使用它:

    String s = <String>resolve();
    

    另一方面,您可能想使用 new T() 无论如何,在C#中。这在Java中是无法做到的。建议的解决方法是使用 Class<T>

    public static <T> T resolve(Class<T> type) {
      try {
        return type.newInstance();
      } catch(Exception e) {
        // deal with the exceptions that can happen if 
        // the type doesn't have a public default constructor
        // (something you could write as where T : new() in C#)
      }
    }
    

    顺便说一句,您还可以使用它来消除前一种情况中的警告,并将运行时异常放置在更合理的行中:

    public static <T> T resolve(Class<T> type) {
      return type.cast(new Object());
    }
    

    这段代码的行为与您作为示例给出的代码完全相同,包括在 T 有什么不同的类型吗 Object

        3
  •  1
  •   Gaim    16 年前

    试试这个 http://java.sun.com/docs/books/tutorial/extra/generics/methods.html

     public static <T> T Resolve()
        {
            return (T) new Object();
        }
    

    当心 (T) 但我不确定这是否正确。我知道通用cast会导致很多问题。我已经花了很多时间。。。

        4
  •  0
  •   Tom Hawtin - tackline    16 年前

    你想要某种工厂:

     public interface MyFactory<T> {
         T newInstance();
     }
    

    public static T resolve<T>(MyFactory<T> factory) {
        return factory.newInstance();
    }