Как работают ссылки на конструктор конструктора Java 8?

Скажем, у нас есть переменная типа IntFunction, которая возвращает целочисленный массив:

IntFunction<int[]> i;

С помощью дженериков Java 8 можно инициализировать эту переменную ссылкой на конструктор следующим образом:

i = int[]::new

Как компилятор Java переводит это в байт-код?

Я знаю, что для других типов, таких как String::new, он может использовать инструкцию invokedynamic, которая указывает на конструктор String java/lang/String.<init>(...), который является всего лишь методом со специальным значением.

Как это работает с массивами, видя, что существуют специальные инструкции для построения массивов?

Ответ 1

Вы можете узнать себя, декомпилировав байт-код java:

javap -c -v -p MyClass.class

Компилятор desugars ссылается на конструктор конструктора массива Foo[]::new на lambda (i -> new Foo[i]), а затем продолжает действовать как с любой другой ссылкой лямбда или метода. Здесь разобранный байт-код этой синтетической лямбда:

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       

(Возвращаемый тип - это Object, потому что стертый тип возвращаемого значения в IntFunction является Object.)