2015-10-21 1 views
0

Voici l'extrait du livre Java Concurrency dans la pratique qui me confondre:Pourquoi pouvons-nous assigner l'objet FutureTask <V> à la variable Future <V>?

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

Comme le code montre, le type de f est l'avenir tandis que les pieds de type s » de est FutureTask. Pourquoi pourrions-nous affecter ft à la variable f?

+0

FutureTask est une implémentation concrète de base de l'interface Future et fournit un traitement asynchrone. –

Répondre

2

Future<V> est une interface implémentée par FutureTask<V>, donc il n'y a rien de mal à le faire. Si une classe C implémente une interface I, vous pouvez affecter cette classe à une variable de type C ainsi qu'à une autre de type I. Sachez que dans la seconde, vous ne pourrez interagir qu'avec le sous-ensemble de méthodes exposées par I, au lieu de l'ensemble proposé par C.

Here la documentation de FutureTask.