2016-08-15 2 views
7

Я пытался использовать эталонный метод с выражением ArrayType[]::new в следующем примере:Эталонный метод с конструктором массива

public class Main 
{ 
    public static void main(String[] args) 
    { 
     test1(3,A[]::new); 
     test2(x -> new A[] { new A(), new A(), new A() }); 

     test3(A::new); 
    } 

    static void test1(int size, IntFunction<A[]> s) 
    { 
     System.out.println(Arrays.toString(s.apply(size))); 
    } 

    static void test2(IntFunction<A[]> s) 
    { 
     System.out.println(Arrays.toString(s.apply(3))); 
    } 

    static void test3(Supplier<A> s) 
    { 
     System.out.println(s.get()); 
    } 
} 

class A 
{ 
    static int count = 0; 
    int value = 0; 

    A() 
    { 
     value = count++; 
    } 

    public String toString() 
    { 
     return Integer.toString(value); 
    } 
} 

Выходной

[null, null, null] 
[0, 1, 2] 
3 

Но что я получаю в методе test1 только массив с нулевыми элементами, не должно быть выражения ArrayType[]::new создать массив с указанным размером и вызвать конструкцию класса A для каждого элемента, например, что происходит при использовании e xpression Type::new в способе test3?

ответ

11

ArrayType[]::new - ссылка метода на конструктор массива. Когда вы создаете экземпляр массива, элементы инициализируются значением по умолчанию для типа массива, а значение по умолчанию для ссылочных типов равно null.

new ArrayType[3] Подобно тому, как производит массив из 3 null ссылок, так же вызова s.apply(3), когда s является ссылкой метод конструктора массива (т.е. ArrayType[]::new) будет производить массив 3 null ссылок.

+0

Благодарим вас за подробное и четкое объяснение. Это было очень полезно и понятно. –

+1

@NarutoBijuMode Добро пожаловать! – Eran

+3

В качестве дополнения желаемая операция может быть достигнута с помощью 'test1 (3, i -> Stream.generate (A :: new) .limit (i) .toArray (A [] :: new)); – Holger

Смежные вопросы