0

Here is the snippet from the book Java Concurrency in Practice that confused me:

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());
            }
        }
    }

As the code shows, the type of f is Future while the ft's type is FutureTask. Why could we assign ft to the variable f?

user2916610
  • 765
  • 1
  • 5
  • 12

1 Answers1

2

Future<V> is an interface implemented by FutureTask<V>, so there is nothing wrong in doing that. If a class C implements an interface I, you can assign that class to a variable having type C as well as to one having type I. Be aware that in the second you will be able to interact only with the subset of methods exposed by I, instead of the whole set offered by C.

Here the documentation of FutureTask.

skypjack
  • 49,335
  • 19
  • 95
  • 187