通过Java上的参数获取类型

通过Java上的参数获取类型,java,generics,gson,Java,Generics,Gson,当然,我对所有这些Java内容都很陌生,所以我有一个问题,我正在尝试反序列化在WCF服务上获得的响应,一切都很好,但是,我正在尝试制作一个通用函数来实现这一点 基本上我做的是 public List<msg> GetService(String method){ List<msg> response = new ArrayList<msg>(); Type msgType = new TypeToken<List<msg>&

当然,我对所有这些Java内容都很陌生,所以我有一个问题,我正在尝试反序列化在WCF服务上获得的响应,一切都很好,但是,我正在尝试制作一个通用函数来实现这一点

基本上我做的是

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
}
public List GetService(字符串方法){
列表响应=新建ArrayList();
类型msgType=newTypeToken(){}.getType();
//取得成果
response=uJSON.fromJson(serviceResponse,msgType);
//uJSON是Gson库的一个实例,只需对其进行反序列化即可
//服务响应和反映所获得消息的类或类型
}
我想做的是获取“msg”类型的泛型,它意味着

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);
}
public void GetInstanceService(字符串方法){
列表响应=新建ArrayList();
类型rType2=newtypetoken(){}.getType();//get java.util.List
//当我试图反序列化时,我只得到一个对象列表
//[java.lang。Object@5c7a987e,java.lang。Object@74b1a7a0]
type2=uJSON.fromJson(新字符串(实体),rType2);
}
但我是这样打电话的

comm.<msgType>GetInstanceService("listTestType");
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
}
comm.GetInstanceService(“listTestType”);
所以,当我调用“GetInstanceService”时,“thing”是“msgType”类型,对于
List
和响应不应该是
List
而不是
List

此外,当我试图通过一个“type”参数显式地传递类型时,它只会导致像这样的编译时错误

comm.<msgType>GetInstanceService("listTestType");
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
}
public void GetInstanceService(类型){
List type2=new ArrayList();//编译时间错误
//或
msgType oType=新的msgType();
Class classType=oType.getClass();
列表类型3;//编译时间错误
}
因此,如果这些尝试都无效,我如何设置反序列化的类型?

由于称为类型擦除的原因,您需要的类对象在运行时不可用

但是,有一个标准的解决方法:将类型标记传递到方法中,如下所示:

public <T> List<T> getService(String method, Class<T> c) {
    // the caller has passed in the class object
    List<T> list = new ArrayList<T>();
    // fill list
    return list;
}
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>>() {});
公共列表getService(字符串方法,c类){
//调用方已传入类对象
列表=新的ArrayList();
//填写清单
退货清单;
}
番石榴类不支持该使用模式。您正在使用类型变量创建类型标记,但没有足够的信息让它从
List
重建
List
。您应该创建一个
TypeToken
实例,其中包含所有必需的编译时信息

文件说:

请注意,实际的类型参数由 子类。以下代码是错误的,因为它只捕获
listType()
方法签名的类型变量;而
是 消失在擦除中:

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

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

Paul Bellora注意到,您还可以接受一个参数
TypeToken token
,并从该
token
在方法内部构造一个
TypeToken

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

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

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

comm.GetInstanceService("listTestType", new TypeToken<msgType>() {});
public void GetInstanceService(String方法,TypeToken令牌){
列表响应=新建ArrayList();
类型rType2=新类型令牌(){}
.where(new TypeParameter(){},token);//where()将“thing”绑定到token
.getType();
type2=uJSON.fromJson(新字符串(实体),rType2);
}
comm.GetInstanceService(“listTestType”,new-TypeToken(){});

方法名称请遵循公认的Java约定
GetInstanceService
应该是
GetInstanceService
东西是类还是实例??如果它是一个实例,它不能用作参数化表达式中的参数。当然,
GetInstanceService(type type)
中的
type
不能用于
new ArrayList()
中,因为它不是一个类……yair:事情是一个类,因为我调用了comm.GetInstanceService(“listTestType”)这样的方法;好吧,我就是听不懂。若我通过类c,我也不能使用List,最后,若我使用“c”反序列化,我也会得到一个对象列表,而不是msgType列表。我有什么错配吗?------------我使用-----------msgType c=new msgType();。。。类classType=(类)c.getClass();。。。comm.getService(“listTestType”,classType);…----然后------List response=new ArrayList();。。。response=(List)uJSON.fromJson(新字符串(实体),c);。。。原因是,我不能做列表或数组列表,我很抱歉,但编辑器不允许空白,以及如何从
t
Class
对象中为
List
构造
类型的
对象?谢谢,这很好。但我就是不明白为什么如果我把一个“Class myClass”作为参数传递,我就不能创建“List”。你有什么线索吗?这只是为了知道这一点。在Java中,类和
class
类型的对象是有区别的。类型和类型为
type
的对象之间的差异同上。类和类型的示例有
int
String
List
Class
对象和
Type
对象的示例有
int.Class
String.Class
new-TypeToken(){}.getType()
@No\u-Name:可以为只有在运行时才知道组件的泛型类型创建
Type
。你必须自己实现一个类来实现
ParameterizedType
接口。+1并注意该方法可以只获取
TypeToken
,然后使用它来组成
TypeToken
。谢谢@PaulBellora,我搜索了该方法,但没有找到:)这是一个漂亮的API。