以下是 Java Concurrency in Practice 这本书的片段让我很困惑:
interface Computable<A, V> {
V compute(A arg) throws InterruptedException;
}
public class Memoizer3<A, V> implements Computable<A, V> {
private final Map<A, Future<V>> cache
= new ConcurrentHashMap<A, Future<V>>();
private final Computable<A, V> c;
public Memoizer3(Computable<A, V> c) { this.c = c; }
public V compute(final A arg) throws InterruptedException {
Future<V> f = cache.get(arg);
if(f == null) {
Callable<V> eval = new Callable<V>() {
@Override
public V call() throws Exception {
return c.compute(arg);
}
};
FutureTask<V> ft = new FutureTask<V>(eval);
//How could it happen???
f = ft;
cache.put(arg, ft);
ft.run();
}
try {
return f.get();
} catch (InterruptedException e) {
throw launderThrowable(e.getCause());
}
}
}
如代码所示, f 的类型是Future,而 ft 的类型是FutureTask。为什么我们可以将 ft 分配给变量 f ?
答案 0 :(得分:2)
Future<V>
是由FutureTask<V>
实现的接口,因此这样做没有错。如果类C
实现了接口I
,则可以将该类分配给类型为C
的变量以及类型为I
的变量。请注意,在第二个中,您只能与I
公开的方法子集进行交互,而不是C
提供的整套方法。
documentation FutureTask
的文档。