• [^] # Re: Fin de la pureté de Java

    Posté par . En réponse à la dépêche Java 8 et NetBeans 8 sont disponibles. Évalué à 8.

    import java.util.Arrays;
    public class Main {
     public static void main(String[] args) {
     System.out.println(
     Arrays.asList(args).stream()
     .map((input) -> "foo" + input)
     .toArray()
     );
     }
    }

    La signature de map est:

    <R> Stream<R> map(Function<? super T, ? extends R> mapper);

    Function est une SAM puisque seul R apply(T t); n'est pas implémentée.

    Si tu regardes du côté de l'implémentation de tout ca, c'est actuellement fait comme ca:

    /javap -c -p Main.class
    Compiled from "Main.java"
    public class Main {
     public Main();
     Code:
     0: aload_0
     1: invokespecial #1 // Method java/lang/Object."<init>":()V
     4: return
     public static void main(java.lang.String[]);
     Code:
     0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
     3: aload_0
     4: invokestatic #3 // Method java/util/Arrays.asList:([Ljava/lang/Object;)Ljava/util/List;
     7: invokeinterface #4, 1 // InterfaceMethod java/util/List.stream:()Ljava/util/stream/Stream;
     12: invokedynamic #5, 0 // InvokeDynamic #0:apply:()Ljava/util/function/Function;
     17: invokeinterface #6, 2 // InterfaceMethod java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
     22: invokeinterface #7, 1 // InterfaceMethod java/util/stream/Stream.toArray:()[Ljava/lang/Object;
     27: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     30: return
     private static java.lang.String lambda0ドル(java.lang.String);
     Code:
     0: new #9 // class java/lang/StringBuilder
     3: dup
     4: invokespecial #10 // Method java/lang/StringBuilder."<init>":()V
     7: ldc #11 // String foo
     9: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     12: aload_0
     13: invokevirtual #12 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     16: invokevirtual #13 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     19: areturn
    }
    

    La raison a très bien été expliquée dans un talk du JVM language submit. C'est assez similaire a ce qui aux bridges methods qui ont été fait pour les generics dans Java 5.

    Maintenant en pratique ca fait des années quoi se balade des lambda illisible de avec 7 lignes de boilerplate et un gros coup d'exec. C'était tellement ridicule que les IDE détectaient les patterns
    lambda et les affichaient avec la syntax 8 pour que ca soit lisible...