Obtaining types through parameters on Java

Certainly I'm quite new in all this Java stuff, so I have a question, I'm trying to deserialize a response obtained on a WCF service, everything works fine, but, I'm trying to make a generic function to do this.

Basically what I do is

public List<msg> GetService(String method){
    List<msg> response = new ArrayList<msg>();

    Type msgType = new TypeToken<List<msg>>(){}.getType();

    //Obtaining result
    response = uJSON.fromJson(serviceResponse, msgType);
    //uJSON is an instance of Gson library, for deserializing it just needs
    //the service response and a Class<T> or Type to reflect the obtained message
}

What I'm trying to do is obtaining the Type "msg" generic, it means...

public <thing> void GetInstanceService(String method){
     List<thing> response = new ArrayList<thing>();

     Type rType2 = new TypeToken<List<thing>>(){}.getType(); //Got java.util.List<thing>

     //And when I'm trying to deserialize I just obtain a List of object 
     //[java.lang.Object@5c7a987e, java.lang.Object@74b1a7a0]

     type2 = uJSON.fromJson(new String(entity), rType2);
}

But I'm calling like this.

comm.<msgType>GetInstanceService("listTestType");

So, when I call "GetInstanceService", "thing" is "msgType" Type, for the List<thing> and also response shouldn't be List<msgType> instead of List <Object>?

Besides, when I'm trying to explicitly pass the type through a "Type" parameter, it just causes me compilation time error like this.

public void GetInstanceService(Type type){
    List<type> type2 = new ArrayList<type>();  //Compilation time error

    //Or
    msgType oType = new msgType();
    Class classType = oType.getClass();
    List<classType> type3;    //Compilation time error
}

So, if none of these attempts was effective, how could I set the type for deserialization?

Answers


Guava class TypeToken does not support that mode of usage. You are creating the type token with a type variable and there not enough information for it to reconstruct List<String> from List<T>. You should create an instance of TypeToken where you have all the required compile-time information.

The documentation says:

Note that it's critical that the actual type argument is carried by a subclass. The following code is wrong because it only captures the <T> type variable of the listType() method signature; while <String> is lost in erasure:

class Util {
  static <T> TypeToken<List<T>> listType() {
    return new TypeToken<List<T>>() {};
  }
}

TypeToken<List<String>> stringListType = Util.<String>listType();

But as said above, you can instantiate the TypeToken at call-site, where all type info are available, and then pass it as a parameter. Something like this:

public <thing> void GetInstanceService(String method, TypeToken<List<thing>> token){
     List<thing> response = new ArrayList<thing>();

     Type rType2 = token.getType();

     type2 = uJSON.fromJson(new String(entity), rType2);
}

comm.GetInstanceService("listTestType", new TypeToken<List<msgType>>() {});

Update

Paul Bellora notes that you can also accept a parameter TypeToken<thing> token, and construct a TypeToken<List<thing>> inside the method from that token:

TypeToken<List<thing>> listToken = new TypeToken<List<thing>>() {}
         .where(new TypeParameter<thing>() {}, token); // where() binds "thing" to token

Need Your Help

What is the best way to include script references in ASP.NET MVC views?

javascript asp.net-mvc markup

As you know, ASP.NET MVC stores view markup in a Views directory, which is hierarchically incompatible with the URL routes that are used in an ASP.NET MVC web application. On the opposite end, in A...

How to integrate OpenID into GlassFish?

java authentication openid glassfish jsr196

I want to integrate OpenID as an authentication mechanism into GlassFish 3.1 (preview). The Development Guide says that JSR 196 could be used to implement custom authentication mechanisms like Open...