Stel dat we een variabele van het type IntFunction
hebben die een integer-array retourneert:
IntFunction<int[]> i;
Met generieke Java 8 is het mogelijk om deze variabele te initialiseren met een constructorreferentie zoals deze:
i = int[]::new
Hoe vertaalt de Java-compiler dit naar bytecode?
Ik weet dat voor andere typen, zoals String::new
, het een invokedynamic
-instructie kan gebruiken die verwijst naar de String-constructor java/lang/String.<init>(...)
, wat slechts een methode is met een speciale betekenis.
Hoe werkt dit met arrays, aangezien er speciale instructies zijn voor het construeren van arrays?
Antwoord 1, autoriteit 100%
Je kunt er zelf achter komen door de Java bytecode te decompileren:
javap -c -v -p MyClass.class
De compiler desugars de array-constructor verwijzingen Foo[]::new
naar een lambda (i -> new Foo[i]
), en gaat dan verder zoals bij elke andere lambda- of methodereferentie. Hier is de gedemonteerde bytecode van deze synthetische lambda:
private static java.lang.Object lambda$MR$new$new$635084e0$1(int);
descriptor: (I)Ljava/lang/Object;
flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
Code:
stack=1, locals=1, args_size=1
0: iload_0
1: anewarray #6 // class java/lang/String
4: areturn
(Het retourtype is Object omdat het gewiste retourtype in IntFunction Object is.)