在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>();
Run Code Online (Sandbox Code Playgroud)
但由于某种原因,我不能让它在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/>");
Run Code Online (Sandbox Code Playgroud)
Tom*_*ine 52
public static <T> T fromXml(Class<T> clazz, String xml) {
Run Code Online (Sandbox Code Playgroud)
被称为:
Thing thing = fromXml(Thing.class, xml);
Run Code Online (Sandbox Code Playgroud)
或更明确地:
Thing thing = MyClass.<Thing>fromXml(Thing.class, xml);
Run Code Online (Sandbox Code Playgroud)
更令人困惑的是,您可以拥有构造函数,这些构造函数都构造泛型类型并且本身具有泛型参数.不记得语法,并且从未见过它在愤怒中使用过(无论如何,你最好使用静态创建方法).
演员表(T)是不安全的,你不能写T.class.因此,将T.class作为参数包含(同样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
);
}
}
Run Code Online (Sandbox Code Playgroud)
我相信JAXB的下一个版本(在6u14?中)对于类中的JAXB这类事情有一些方便的方法.
在Java中,泛型是仅编译时的数据,在运行时会丢失.所以,如果你调用这样的方法,JVM就无法知道它是什么T.class.解决此问题的常用方法是将类实例对象作为参数传递给方法,如下所示:
public static <T> T fromXml(Class<T> clazz, String xml) {
try {
JAXBContext context = JAXBContext.newInstance(clazz);
Unmarshaller um = context.createUnmarshaller();
return (T)um.unmarshal(new StringReader(xml));
} catch (JAXBException je) {
throw new RuntimeException("Error interpreting XML response", je);
}
}
fromXml(SomeSubObject.class, "<xml/>");
Run Code Online (Sandbox Code Playgroud)
像 Java 这样的方法有这样的Collections.emptySet()签名:
public static final <T> Set<T> emptySet()
Run Code Online (Sandbox Code Playgroud)
并被这样调用:
Set<Foo> foos = Collections.<Foo>emptySet();
Run Code Online (Sandbox Code Playgroud)
Mockito 的anyObject()方法是另一个例子。我个人认为这两种语法都不是非常棒。将类型作为方法参数传入是可行的,但总是感觉很笨拙。以emptySet()看起来更简洁的方式提供参数,但方法允许指定类型并不总是很明显。
| 归档时间: |
|
| 查看次数: |
53414 次 |
| 最近记录: |