为什么我们可以将FutureTask <v>对象分配给Future <v>变量?

时间:2015-10-21 06:09:10

标签: java concurrency future futuretask

以下是 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

1 个答案:

答案 0 :(得分:2)

Future<V>是由FutureTask<V>实现的接口,因此这样做没有错。如果类C实现了接口I,则可以将该类分配给类型为C的变量以及类型为I的变量。请注意,在第二个中,您只能与I公开的方法子集进行交互,而不是C提供的整套方法。

documentation FutureTask的文档。