L'expression Lambda donne une erreur de syntaxe "jetons invalides" en Java


Je viens de commencer à en apprendre davantage sur l'expression Lambda et j'ai fait quelque chose comme ceci:

public class LambdaTest {

    public static void main(String[] args) {
        int num = returnNumber((num) -> { return 4 });
    }

    public static int returnNumber(int num) {
        return num;
    }
}

Mais cela me donne une erreur: "jetons invalides". Voici une image:

Quelqu'un peut-il m'expliquer ce qui ne va pas? C'est juste un test.

J'ai Java 1.8 pris en charge dans mon installation Eclipse (Luna 4.4).

Author: lbalazscs, 2014-12-05

3 answers

Il y a quelques restrictions sur ce qui peut être fait dans le corps du lambda, dont la plupart sont assez intuitives-un corps lambda ne peut pas "casser" ou "continuer" hors du lambda, et si le lambda renvoie une valeur, chaque chemin de code doit renvoyer une valeur ou lancer une exception, et ainsi de suite. Ce sont à peu près les mêmes règles que pour une méthode Java standard, elles ne devraient donc pas être trop surprenantes.

Référence : http://www.oracle.com/technetwork/articles/java/architect-lambdas-part1-2080972.html

Le corps de la méthode a pour effet d'évaluer le corps lambda, si est une expression, ou d'exécuter le corps lambda, s'il s'agit d'un bloc; si un résultat est attendu, il est renvoyé par la méthode.

Si le résultat du type de fonction est nul, le corps lambda est soit un expression d'instruction ou un bloc compatible void.

Référence : http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27.4

 1
Author: İlker Korkut, 2014-12-05 18:32:53

L'erreur de syntaxe est assez simple. Il dit qu'il y a un ; manquant après une instruction et ce n'est en aucun cas autre qu'avec des instructions en dehors des expressions lambda. Si vous écrivez (num) -> { return 4 }, il doit y avoir un point-virgule après return 4 comme il devrait être à chaque endroit où vous pouvez écrire return 4 (je suis sidérée pourquoi personne d'autre n'était capable de vous dire que).

, Vous pouvez écrire une expression lambda retour d'un int de deux façons, soit comme (num) -> { return 4; }, ou, beaucoup plus simple, comme num -> 4 (ici, sans point-virgule).

Mais, bien sûr, vous ne pouvez pas appeler returnNumber(int num) avec une expression lambda comme paramètre car elle attend un int et non un interface fonctionnel. Votre compilateur vous dira qu'une fois que vous avez corrigé l'erreur de syntaxe structurelle du point-virgule manquant.

 1
Author: Holger, 2014-12-08 11:05:44

Les lambdas ne sont que des implémentations pour la méthode d'interface fonctionnelle (interfaces avec une méthode abstraite), mais dans le cas de

returnNumber(int num)

Lambdas ne peut pas être utilisé car:

  • int n'est pas une interface fonctionnelle
  • donc lambdas ne peut pas être utilisé pour fournir l'implémentation de sa seule méthode abstraite (puisque les types primitifs sont primitifs - ils n'ont pas de méthodes).

Avant lambdas pour exécuter la méthode comme

method(SomeInterface si){...}

Vous le feriez besoin de créer une classe distincte qui implémenterait cette interface

class MyClass implements SomeInterface{
    void method(Type1 arg1, Type2 arg2){
        //body
    }
}

...
MyClass mc = new MyClass();
method(md);

Ou ajouter son implémentation à la volée en créant une classe anonyme

method(new SomeInterface{
    void method(Type1 arg1, Type2 arg2){
        //body
    }
});

Les lambdas peuvent raccourcir ce processus en ignorant cet idiome et en vous permettant de vous concentrer uniquement sur les types d'arguments et l'implémentation.

Donc au lieu de

new SomeInterface{
    void method(Type1 arg1, Type2 arg2){
        //body
    }
}

, Vous pouvez simplement écrire

(Type1 arg1, Type2 arg2) -> { body } // you can actually shorten it even farther 
                                     // but that is not important now
 0
Author: Pshemo, 2014-12-05 18:28:34