Java 获取泛型类的属性值
我使用的是Java v1.8,代码如下:Java 获取泛型类的属性值,java,Java,我使用的是Java v1.8,代码如下: public <T> ApiResponse<T> execute(Call call, Type returnType) throws ApiException { try { Response response = call.execute(); T data = handleResponse(response, returnType); ApiResponse<
public <T> ApiResponse<T> execute(Call call, Type returnType) throws ApiException {
try {
Response response = call.execute();
T data = handleResponse(response, returnType);
ApiResponse<T> apiResponse = new ApiResponse<T>(response.code(), response.headers().toMultimap(), data);
return apiResponse;
} catch (IOException e) {
throw new ApiException(e);
}
}
public ApiResponse execute(Call-Call,Type-returnType)抛出ApiException{
试一试{
Response=call.execute();
T数据=HandlerResponse(响应,返回类型);
ApiResponse ApiResponse=新的ApiResponse(response.code(),response.headers().toMultimap(),data);
返回响应;
}捕获(IOE异常){
抛出新异常(e);
}
}
因此,这将进行API调用,并根据类型returnType
解析响应。我知道每个API调用都会使用bodyrequestId
中的参数进行响应
由于我不知道
returnType
的类型,有没有办法获取属性requestId
。它应该在数据中
..您已经定义了一个类型变量T
。这个类型变量没有任何界限;您将它声明为
,意思是T可以是任何东西。甚至反对。特别是,Object
是一种常见类型,任何T都必须是的子类型,并且Object没有requestId。因此,您不能调用.getRequestId()
或.requestId
或您对requestId
的任何含义。解决方案是bindT:告诉java T不能只是“任何东西”,它只能是具有特定属性的类型。具体地说,告诉它只能是任何抽象类或接口,它是所有Api响应返回类型的超类型,其中包含.getRequestId()
方法:public….
是您想要的
这里还有第二个问题-您的泛型刚刚被破坏。这个代码毫无意义
泛型是编译器想象出来的:编译器使用泛型将事物联系在一起。它并不是“幸存”下来的东西——T只是在编译之后消失了。编译器在编译过程中使用它进行一些额外的错误检查和方便,然后它就消失了。因此,您编写的任何泛型都必须在编译过程中添加一些有用的内容,否则就会被误导和/或使事情变得混乱
换句话说,任何类型变量必须始终在至少两个位置使用——其目的是链接事物。例如,在此方法中:
public <T> T identity(T in) { return in; }
即使您确实希望编译器出错,也无法从中获益
您不应该在此处使用类型
。除非您正在编写注释处理器或反射库(通常您都不需要),否则几乎不应该使用它
这里有两个选项:
- ApiResponse类型始终是一个简单的类。i、 e.它是一个
twitter提到的
类或
或诸如此类的东西,而不是一个newweetresponse
列表或
。在这种情况下,您可以使用int
而不是Type:Class
。这将[A]保证您只能使用TwitterType的某个子类型的T调用public-ApiResponse-execute(Call-Call,Class-twitterType){}
,并且[B]将事物正确地联系在一起:传递例如execute
以执行意味着它返回TwitterAttentions.class
,而不是薛定谔猫的反应,可以分配给任何你想要的,即使它没有任何意义ApiResponse
- 或者,如果ApiResponse可以是一个
,那么它应该是一个超级类型的令牌(您可以在web上搜索“java超级类型令牌”,它需要一些解释,并且有很多很好的教程),这样您就可以将泛型绑定在一起,并在运行时检索类型,这大概是列表
想要的HandlerResponse
类的情况:
public interface TwitterType {
public String getRequestId();
}
public class TwitterMentions implements TwitterType {
@Override public String getRequestId() {
..
}
public List<TwitterMention> getMentions() {
..
}
}
public <T extends TwitterType> ApiResponse<T> execute(Call call, Class<?> returnType) throws ApiException { ... }
公共接口TwitterType{
公共字符串getRequestId();
}
公共类twitter实现了TwitterType{
@重写公共字符串getRequestId(){
..
}
公共列表{
..
}
}
公共ApiResponse execute(调用,类returnType)抛出ApiException{…}
您已经定义了一个类型变量T
。这个类型变量没有任何界限;您将它声明为
,意思是T可以是任何东西。甚至反对。特别是,Object
是一种常见类型,任何T都必须是的子类型,并且Object没有requestId。因此,您不能调用.getRequestId()
或.requestId
或您对requestId
的任何含义。解决方案是bindT:告诉java T不能只是“任何东西”,它只能是具有特定属性的类型。具体地说,告诉它只能是任何抽象类或接口,它是所有Api响应返回类型的超类型,其中包含.getRequestId()
方法:public….
是您想要的
这里还有第二个问题-您的泛型刚刚被破坏。这个代码毫无意义
泛型是编译器想象出来的:编译器使用泛型将事物联系在一起。它并不是“幸存”下来的东西——T只是在编译之后消失了。编译器在编译过程中使用它进行一些额外的错误检查和方便,然后它就消失了。因此,您编写的任何泛型都必须在编译过程中添加一些有用的内容,否则就会被误导和/或使事情变得混乱
换句话说,任何类型变量必须始终在至少两个位置使用——其目的是链接事物。例如,在此方法中:
public <T> T identity(T in) { return in; }
即使您确实希望编译器出错,也无法从中获益
您不应该在此处使用类型
。你几乎不应该使用它,除非