如何使用非通用输入列表调用通用方法
How to invoke generic method with a list of non-generic inputs
我有以下 class:
public class RemoteService {
private static class QueryEntry<T> {
public final IQueryInput<T> input;
public final FutureCallback<T> callback;
// constructor not shown here
}
private final List<QueryEntry<?>> mQueries;
public <T> Result doStuff(IQueryInput<T> input, FutureCallback<T> callback) {
// Simplified code here
if(mIsServiceAlive) {
return actuallyMakeQuery(input, callback);
} else {
// will make it happen later
mQueries.add(new QueryEntry(input, callback));
}
}
private <T> Result actuallyMakeQuery(IQueryInput<T> input, FutureCallback<T> callback) {
// ... magic
return result;
}
//.. other code
private void onServiceAlive() {
//This method is called when this service is connected to dependencies
//and is now live. Here we want to actually make the queries ...
for(final QueryEntry<?> entry : mQueries) {
// Compile error here because I can't reference entry<T>.input
// as T is now lost .... is there any where I can make this happen?
actuallyMakeQuery(entry.input, entry.callback);
}
mQueries.clear();
}
}
这里的问题很简单 -> 我可以用 mQueries
调用 actuallyMakeQuery
吗?我不这么认为,因为当我缓存所有输入时,我丢失了 T
,因为 mQueries
正在使用 QueryEntry<?>
。我也无法更改 doStuff
签名,因为它被定义为其他地方的接口。我可以在这里做什么?
您可以通过引入额外的间接级别来捕获通配符:
private <T> Result actuallyMakeQuery(IQueryInput<T> input, FutureCallback<T> callback) {
// ... magic
return new Result();
}
private <T> Result actuallyMakeQuery(QueryEntry<T> entry) {
// no wildcards anymore
return actuallyMakeQuery(entry.input, entry.callback);
}
此外,您在
中省略了<>
mQueries.add(new QueryEntry<>(input, callback));
不必要地把它变成原始类型。
然后您可以使用该新方法:
private void onServiceAlive() {
// This method is called when this service is connected to dependencies
// and is now live. Here we want to actually make the queries ...
for (final QueryEntry<?> entry : mQueries) {
// no problem here anymore
actuallyMakeQuery(entry);
}
mQueries.clear();
}
我有以下 class:
public class RemoteService {
private static class QueryEntry<T> {
public final IQueryInput<T> input;
public final FutureCallback<T> callback;
// constructor not shown here
}
private final List<QueryEntry<?>> mQueries;
public <T> Result doStuff(IQueryInput<T> input, FutureCallback<T> callback) {
// Simplified code here
if(mIsServiceAlive) {
return actuallyMakeQuery(input, callback);
} else {
// will make it happen later
mQueries.add(new QueryEntry(input, callback));
}
}
private <T> Result actuallyMakeQuery(IQueryInput<T> input, FutureCallback<T> callback) {
// ... magic
return result;
}
//.. other code
private void onServiceAlive() {
//This method is called when this service is connected to dependencies
//and is now live. Here we want to actually make the queries ...
for(final QueryEntry<?> entry : mQueries) {
// Compile error here because I can't reference entry<T>.input
// as T is now lost .... is there any where I can make this happen?
actuallyMakeQuery(entry.input, entry.callback);
}
mQueries.clear();
}
}
这里的问题很简单 -> 我可以用 mQueries
调用 actuallyMakeQuery
吗?我不这么认为,因为当我缓存所有输入时,我丢失了 T
,因为 mQueries
正在使用 QueryEntry<?>
。我也无法更改 doStuff
签名,因为它被定义为其他地方的接口。我可以在这里做什么?
您可以通过引入额外的间接级别来捕获通配符:
private <T> Result actuallyMakeQuery(IQueryInput<T> input, FutureCallback<T> callback) {
// ... magic
return new Result();
}
private <T> Result actuallyMakeQuery(QueryEntry<T> entry) {
// no wildcards anymore
return actuallyMakeQuery(entry.input, entry.callback);
}
此外,您在
中省略了<>
mQueries.add(new QueryEntry<>(input, callback));
不必要地把它变成原始类型。
然后您可以使用该新方法:
private void onServiceAlive() {
// This method is called when this service is connected to dependencies
// and is now live. Here we want to actually make the queries ...
for (final QueryEntry<?> entry : mQueries) {
// no problem here anymore
actuallyMakeQuery(entry);
}
mQueries.clear();
}