至于什么是泛型通配符,我是知道的,但是不知道具体在项目里的使用场景,比如哪些情况下,我们创建的类或者接口需要用到泛型通配符呢
阿神2017-04-18 10:51:24
Remember this sentence from the book Effective Java: Producer Extends, Consumer Super.
It’s explained in detail here: http://stackoverflow.com/ques...
Supplement
TreeMap
has a constructor:
public TreeMap(Comparator<? super K> comparator);
You can think about why you need to specify the type Comparator<? super K> instead of Comparator<K> or Comparator<? extends K>?
PHPz2017-04-18 10:51:24
I don’t write Java, but all generics are interlinked. I happened to be looking at Taobao OPEN's SDK at this time. This is a real example that best explains generic wildcards.
I specially found a Java version of SDK, see: https://github.com/ggd543/tao...
-- url: https://github.com/ggd543/taobao-sdk-java/blob/master/src/main/java/com/taobao/api/TaobaoClient.java
/**
* 执行TOP公开API请求。
* @param <T>
* @param request 具体的TOP请求
* @return
* @throws ApiException
*/
public <T extends TaobaoResponse> T execute(TaobaoRequest<T> request) throws ApiException ;
All API requests are made through subclasses of execute
来操作的,而这个方法就采用的 ? extends T
通配符上界,来限制返回的对象必须是 TaobaoResponse
.
To put it simply, it is a constraint.
From the perspective of Taobao SDK, the greatest value of the wildcard upper bound is that the results returned by all Taobao SDK requests will have a code
、msg
and other common parameters to indicate the request status of the API.
Okay, let’s go back and look at the specific implementation of execute
:
if(this.needCheckRequest==true){
try{
request.check();//if check failed,will throw ApiRuleException.
}catch(ApiRuleException e){
T localResponse=null;
try {
localResponse=request.getResponseClass().newInstance();
} catch (InstantiationException e2) {
throw new ApiException(e2);
} catch (IllegalAccessException e3) {
throw new ApiException(e3);
}
localResponse.setErrorCode(e.getErrCode());
localResponse.setMsg(e.getErrMsg());
//localResponse.setBody("this.");
return localResponse;
}
}
Notice the subclass of catch
体中 localResponse
,他的类型 T
,但这个T并不是简单的一个Object对象,由于前面已经限定 T
的类型必须是 TaobaoResponse
here.
That means, when the definition of T
进行实例后,其类型至少是 TaobaoResponse
的子类,而对于 TaobaoResponse
is this:
-- url: https://github.com/ggd543/taobao-sdk-java/blob/master/src/main/java/com/taobao/api/TaobaoResponse.java
public abstract class TaobaoResponse implements Serializable {
private static final long serialVersionUID = 5014379068811962022L;
@ApiField("code")
private String errorCode;
@ApiField("msg")
private String msg;
// more
}
So you can directly see code like this:
localResponse.setErrorCode(e.getErrCode());
Look, isn’t it interesting? All common parameters can be processed uniformly.
So from the perspective of Taobao SDK, this is the meaning of generic wildcards.