我在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
}
}
}
最佳答案
在发布的代码段中,您需要进行强制转换,因为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 {}
让我们逐步解决问题。您希望能够打电话
req.add(new BaseRequest<ExtObj1>());
req.add(new BaseRequest<ExtObj2>());
req.add(new BaseRequest<ExtObj3>());
其中
ExtObj[1|2|3] extends BaseObj
。给定List接口(interface):List<T> {
void add(T el);
}
我们需要找到
BaseRequest<ExtObj1>
,BaseRequest<ExtObj2>
和BaseRequest<ExtObj3>
的通用父类(super class)型。一种父类(super class)是BaseRequest<?>
,另一种是BaseRequest<? extends BaseObj>
。我选择了第二个,因为它是最严格的限制。您应该知道在Java中BaseRequest<ExtObj1>
不是BaseRequest<BaseObj>
的子类型,因为泛型是不变的。既然我们对mRequests有了正确的声明,那么找到
Executor.add()
的API就很简单了。顺便说一句,如果您需要的方法主体真的那么简单,那么您甚至不需要type参数:public void add(BaseRequest<? extends BaseObj> request) {
mRequests.add(request);
}