2015-04-04 3 views
31

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

IntFunction<int[]> i; 

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

i = int[]::new 

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

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

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

+1

В Java, они называются ссылки, а не указатели. Обычно ссылки предоставляют почти все операции указателя, за исключением того, что вы не можете добавить произвольное смещение к ссылке или выполнять другие виды математических операций над ними. –

ответ

37

Вы можете узнать сами по декомпиляции Java байткод:

javap -c -v -p MyClass.class 

Компилятор desugars ссылки конструктора массива Foo[]::new к лямбда (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  

(это возвращаемый типа объект, поскольку стертый типа возвращаемого в IntFunction является Object.)