简体   繁体   中英

Generic class type java

I want to write one generic object mapping json to java, for insert went is needed.

So i was making the next code

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

    }
}

But my problem is that the T.class is not working, how i can get the class of one generic value? because if i put getObject(String stringJSON, class<T> clazzT) i have to add always class and if i put like a property class clazzT in the object i will have a null pointerException.

So how i can fix the problem, for use only the definition of the object like Converter?

And i see in some implementation of REST like easyRest and CXF, that they use the Class of the type for make the tranformation between String and Object, like

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

They use some automatique way, i want to have the one class similar like that

You need to add the Class<T> as a parameter to the getObject() method, so that you are able to fetch T 's Runtime Class type:

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

And also, re-factor all the references to the method.

You can't, because of type erasure.

What you can do is to bind your generic type with an interface:

public class JSONConverter<T extends IMyInterface>

Then you can de-serialize as:

mapper.readValue(stringJSON, IMyInterface.class);

You might even be able to annotate your classes implementing IMyInterface so that the sub-type is known by Jackson at de-serialization.

You can't do that. Tipically, the type is passed as parameter:

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

Actually, there is a way to obtain T.class runtime by reflection, but I don't recommend it you.

EDIT

Obtain T.class on runtime:

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

Sometimes I get NPE using that, I don't recommend it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM