1

J'ai répliqué une exception lancée en essayant d'utiliser type intersection de type variable pour capturer lambdas; Plus précisément, de reproduire, je tentais d'attraper un lambda comme F<A, F extends Consumer<A> & Serializable>:ClassCastException lors de la capture d'un lambda sérialisable avec des paramètres de type intersection

public class Consumers { 

    public static <A, F extends Consumer<A> & Serializable> 
    Consumer<A> serializable(F action) { 
     return action; 
    } 

    public static <A> Consumer<A> vary(Consumer<? super A> action) {...} 

    private static final Consumer<Object> DOES_NOTHING = 
      serializable(a -> {}); 

    public static <A> Consumer<A> doesNothing() { 
     return vary(DOES_NOTHING); 
    } 

    ... 
} 

Consumer<String> action = Consumers.doesNothing(); // throws class cast exception 

Voici un exemple de l'exception levée:

java.lang.ClassCastException: [insert lambda name] cannot be cast to java.util.function.Consumer 

Je suis en mesure d'utiliser Consumers.serializable avec ou locale variables d'instance; cette exception est levée lorsque vous essayez d'initialiser des variables statiques.

Est-ce correct? J'utilise le dernier Eclipse Oxygen, JDK u112.

+1

Le compilateur eclipse est différent du compilateur JDK et il y a pas mal de différences dans leur comportement. Peut-être essayer à l'aide du compilateur JDK? 'javac' ou maven ou tout ce que vous utilisez qui utilise le compilateur JDK. –

Répondre

0

Cela ne devrait pas être autorisé: javac se plaint:

Consumers.java:??: error: incompatible types: cannot infer type-variable(s) A,F 
      serializable(a -> {}); 
         ^
    (argument mismatch; Consumer<Object> cannot be converted to INT#1) 
    where A,F are type-variables: 
    A extends Object declared in method <A,F>serializable(F) 
    F extends Consumer<A>,Serializable declared in method <A,F>serializable(F) 
    where INT#1 is an intersection type: 
    INT#1 extends Object,Serializable,Consumer<Object> 

Il est en fait un compilateur Eclipse bug, fixé à 4,6 M6 (Neon), et il a déjà été remarqué dans ce other question.

+0

Ouais; Je viens d'utiliser javac et j'ai reçu la même erreur; Oxygen compile ceci, mais jette une exception. Bien que, ce qui diffère de la [autre question] (http://stackoverflow.com/questions/35268927/lambda-and-cast-intersection-type-eclipse-compiler-bug) vous lié est que le consommateur est un SAM et Serializable est un ZAM; vous penseriez que cela compilerait (javac) ou ne lancerait pas une exception (Eclipse Oxygen). Il semble étrange que '(Consumer & Serializable)' attrape lambdas mais ' & Serializable> ... (T arg)' ne le fait pas (mais seulement pour les champs statiques); Je vais marquer cette réponse. Merci. – bizness86