Java中没有泛型参数的泛型方法 [英] Generic method in Java without generic argument

查看:755
本文介绍了Java中没有泛型参数的泛型方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中,我可以做到这一点:

  //这是C#
static T SomeMethod< T> ()其中T:new()
{
Console.WriteLine(Typeof T:+ typeof(T));
返回新的T();
}

//然后调用这个方法
SomeMethod< SomeClassName>();

但由于某种原因,我无法在Java中使用它。



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

  //这是Java,但不起作用
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);
}
}

//此外调用不起作用...
fromXml< SomeSubObject>(< xml />);


解决方案

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)是不安全的,你不能写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));
尝试{
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 类中为这类事物提供了一些便利方法。


In C# I can do actually this:

//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>();

But for some reason I can't get it to work in Java.

The thing I want to do is, to create a static method on a superclass, so the subclasses can be converted to 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/>");

解决方案

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

Called as:

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

or more explicitly:

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

To be even more confusing you can have constructors that both construct a generic type and have a generic parameter themselves. Can't remember the syntax and have never seen it used in anger (you are probably better off with a static creation method anyway).

The cast (T) is unsafe, and you can't write T.class. So include the T.class as an argument (as JAXBContext.newInstance does) and throw a relevant exception if the type is wrong.

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
         );
    }
}

I believe the next version of JAXB (in 6u14?) has some convenience methods for this sort of thing in the JAXB class.

这篇关于Java中没有泛型参数的泛型方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆