通用类类型java

时间:2015-02-17 09:59:27

标签: java generics

我想编写一个将json映射到java的通用对象,因为需要插入。

所以我正在制作下一个代码

public class JSONConverter<T> {

    public String getStringJSON(T obj{
        ObjectMapper mapper = new ObjectMapper();
        if(obj!=null){
            try {
                return mapper.writeValueAsString(obj);
            } catch (IOException e) {
            }
        }
        //mapper.writeValueAsString(obj);

    }

    public T getObject(String stringJSON){
        ObjectMapper mapper = new ObjectMapper();
        mapper.readValue(stringJSON, T.class);

    }
}

但我的问题是T.class不工作,我怎么能得到一个通用值的类?因为如果我放getObject(String stringJSON, class<T> clazzT)我必须添加始终类,如果我像对象一样放置属性类clazzT,我会有一个空的pointerException。

那么我如何解决问题,只使用像Converter这样的对象的定义?

我在REST的一些实现中看到,比如easyRest和CXF,他们使用类型的类来进行String和Object之间的转换,比如

@POST
@Path("/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response someService(SomeClass obj) 

他们使用一些自动化的方式,我希望有一个类似的那个

4 个答案:

答案 0 :(得分:1)

您需要将Class<T>作为参数添加到getObject()方法,以便您能够获取T的运行时Class类型:

public T getObject(String stringJSON, Class<T> clazz){
    ObjectMapper mapper = new ObjectMapper();
    mapper.readValue(stringJSON, clazz);
}

并且,重新考虑对方法的所有引用。

答案 1 :(得分:1)

由于类型擦除,你不能这样做。

可以做的是将您的泛型类型与接口绑定:

public class JSONConverter<T extends IMyInterface>

然后你可以反序列化为:

mapper.readValue(stringJSON, IMyInterface.class);

您甚至可以注释实现IMyInterface的类,以便Jackson在反序列化时知道子类型。

答案 2 :(得分:1)

你做不到。简而言之,类型作为参数传递:

public T getObject(String stringJSON, Class<T> clazz){
    ObjectMapper mapper = new ObjectMapper();
    mapper.readValue(stringJSON, clazz);
}

实际上,有一种方法可以通过反射获得T.class运行时,但我不推荐你。

修改

在运行时获取T.class

  private Class<T> type = (Class<T>) ((ParameterizedType) getClass()
            .getGenericSuperclass())
            .getActualTypeArguments()[0];

有时我会使用NPE,我不推荐它。

答案 3 :(得分:0)

如果在类型定义中捕获T的值,您可以通过TypeTools之类的内容检索它:

class StringConverter extends JsonConverter<String> { //...
}

Class<?> t = TypeResolver.resolveRawArgument(JsonConverter.class, StringConverter.class);
assert t == String.class;