我正在努力解决Java中泛型的这个方面.希望有人可以帮我看看方法.
我有一个包含对象列表的类.这段代码有效,但我想摆脱演员表.我怎样才能使这更通用?
public class Executor {
List<BaseRequest<BaseObj>> mRequests = new ArrayList<BaseRequest<BaseObj>>();
public Executor() {
}
@SuppressWarnings("unchecked")
public <T extends BaseObj> void add(final BaseRequest<T> request) {
mRequests.add((BaseRequest<BaseObj>) request);
}
public void execute() {
for (BaseRequest<BaseObj> r : mRequests) {
// DO SOMETHING WITH r
}
}
}
Run Code Online (Sandbox Code Playgroud)
在发布的片段中,您需要强制转换,因为BaseRequest<? extends BaseObj>它不是子类型BaseRequest<BaseObj>,并且由于类型擦除而无法在运行时检查强制转换,这就是编译器警告您的原因.但是如果你改变声明mRequests:
public class Executor {
List<BaseRequest<? extends BaseObj>> mRequests = new ArrayList<>();
public Executor() {
}
public <T extends BaseObj> void add(final BaseRequest<T> request) {
mRequests.add(request);
}
public void execute() {
for (BaseRequest<? extends BaseObj> r : mRequests) {
// DO SOMETHING WITH r
}
}
}
class BaseRequest<T> {}
class BaseObj {}
Run Code Online (Sandbox Code Playgroud)
让我们一步一步解决问题.你希望能够打电话
req.add(new BaseRequest<ExtObj1>());
req.add(new BaseRequest<ExtObj2>());
req.add(new BaseRequest<ExtObj3>());
Run Code Online (Sandbox Code Playgroud)
哪里ExtObj[1|2|3] extends BaseObj.给定List接口:
List<T> {
void add(T el);
}
Run Code Online (Sandbox Code Playgroud)
我们需要找到一个共同的超类型BaseRequest<ExtObj1>,BaseRequest<ExtObj2>和BaseRequest<ExtObj3>.一个超类型是BaseRequest<?>另一个超级类型BaseRequest<? extends BaseObj>.我选择了第二个,因为它是最可能限制的.您应该知道Java BaseRequest<ExtObj1>中不是子类型,BaseRequest<BaseObj>因为泛型是不变的.
现在我们有了mRequests的正确声明,找到API Executor.add()非常简单.顺便说一句,如果你需要的方法体非常简单,你甚至不需要type参数:
public void add(BaseRequest<? extends BaseObj> request) {
mRequests.add(request);
}
Run Code Online (Sandbox Code Playgroud)