web-dev-qa-db-fra.com

Pourquoi les variables dans lambdas doivent-elles être définitives ou effectivement définitives?

Lorsque j'écris ce code, je reçois une erreur de compilation qui dit: 'Les variables dans lambdas doivent être finales ou effectivement définitives'.

Maintenant, je comprends ce qui supprime le i de la ligne:

futureLists.add (executorService.submit (() -> "Bonjour tout le monde" + i));

résout le problème. 

Mais je veux savoir que pourquoi une telle exigence existe?

Selon le JLS , tout ce qui est écrit est:

Toute variable locale, paramètre formel ou paramètre d'exception utilisé mais non déclaré dans une expression lambda doit soit être déclaré final, soit être effectivement final, sinon une erreur de compilation survient lors de la tentative d'utilisation.

Mais cela n’indique pas pourquoi une telle exigence existe. Mais pourquoi les ingénieurs de Java ont-ils imposé une telle exigence pour les lambdas?

public class test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
         ExecutorService executorService = Executors.newFixedThreadPool(10);

         List<Future<String>> futureLists = new ArrayList<>();

         for (int i = 0; i < 20; i++) {
             futureLists.add(executorService.submit( () -> "Hello world" + i));
             }

         for (Future<String> itr:futureLists) {
             System.out.println(itr.get());
            }
       }
   }
5
Duke Sen

Il est lié à la programmation multi-thread.

Les variables locales en Java ont jusqu'à présent été immunisées contre la concurrence. et des problèmes de visibilité car ils ne sont accessibles qu’au fil l'exécution de la méthode dans laquelle ils sont déclarés. Mais un lambda peut être passé du thread qui l'a créé à un autre thread, et que l'immunité serait donc perdue si le lambda, évalué par le deuxième fil, ont eu la possibilité de muter des variables locales. - La source

9
snr

La raison probable pour laquelle les ingénieurs Java ont fait cela était de rendre le code Java plus durable. Lorsque l'on permet à la variable d'être non finale, sa valeur peut être modifiée à partir de pratiquement n'importe où dans le programme. Cela pourrait potentiellement causer des problèmes de concurrence.

Il est mentionné dans this document:

La restriction aux variables finales en fait interdit l'accès aux variables locales à changement dynamique, dont la capture risquerait de poser des problèmes de simultanéité. Par rapport à la restriction finale, cela réduit le fardeau administratif des programmeurs.

1
NocNit

Les choses immuables sont faciles à distribuer. Plusieurs consommateurs peuvent les utiliser sans avoir à s'inquiéter de quelqu'un d'autre qui aurait pu changer la valeur. Les fonctions Lambda en Java entraînent Java dans le domaine de la programmation fonctionnelle où vous pouvez la transmettre. Ceci est très utile dans la programmation distribuée. Puisqu'il peut y avoir plusieurs processeurs, il est préférable de transmettre les valeurs finales plutôt que d'ajouter une surcharge de gestion de la concurrence.

0
noobCoder