Java 中不带泛型参数的泛型方法

2022-09-01 05:09:20

在C#中,我实际上可以这样做:

//This is C#
static T SomeMethod<T>() where T:new()
{
  Console.WriteLine("Typeof T: "+typeof(T));
  return new T();
}

//And call the method here
SomeMethod<SomeClassName>();

但是由于某种原因,我无法让它在Java中工作。

我想做的是,在超类上创建一个静态方法,以便子类可以转换为XML。

//This is Java, but doesn't work
public static T fromXml<T>(String xml) {
  try {
    JAXBContext context = JAXBContext.newInstance(T.class);
    Unmarshaller um = context.createUnmarshaller();
    return (T)um.unmarshal(new StringReader(xml));
  } catch (JAXBException je) {
    throw new RuntimeException("Error interpreting XML response", je);
  }
}

//Also the call doesn't work...
fromXml<SomeSubObject>("<xml/>");

答案 1
public static <T> T fromXml(Class<T> clazz, String xml) {

称为:

Thing thing = fromXml(Thing.class, xml);

或更明确地说:

Thing thing = MyClass.<Thing>fromXml(Thing.class, xml);

为了更加令人困惑,您可以拥有既构造泛型类型又具有泛型参数本身的构造函数。不记得语法,也从未见过它在愤怒中使用(无论如何,使用静态创建方法可能更好)。

演员阵容不安全,你不能写T.class。因此,将 T.class作为参数包括在内(就像这样),如果类型错误,则引发相关异常。(T)JAXBContext.newInstance

public static <T> T fromXml(Class<T> clazz, String xml) {
    try {
        JAXBContext context = JAXBContext.newInstance(clazz);
        Unmarshaller um = context.createUnmarshaller();
        Object obj = um.unmarshal(new StringReader(xml));
        try {
            return clazz.cast(obj);
        } catch (ClassCastException exc) {
             throw new RelevantException(
                 "Expected class "+clazz+
                  " but was "+obj.getClass()
             );
        }
    } catch (JAXBException exc) {
        throw new RelevantException(
            "Error unmarshalling XML response",
            exc
         );
    }
}

我相信下一个版本的JAXB(在6u14中?)为类中的这种事情提供了一些方便的方法。JAXB


答案 2

像Java这样的方法有一个这样的签名:Collections.emptySet()

public static final <T> Set<T> emptySet()

并被称为这样:

Set<Foo> foos = Collections.<Foo>emptySet();

Mockito的方法是另一个例子。我个人并不认为这两种语法都很棒。将类型作为方法参数传递有效,但总是感觉笨拙。以这样做的方式提供参数似乎更干净,但方法允许指定类型并不总是很明显。anyObject()emptySet()


推荐