2016-08-15 1 views
7

Ich versuchte Referenzmethode mit Ausdruck ArrayType[]::new im folgenden Beispiel zu verwenden:Referenzmethode mit Array-Konstruktor

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); 
    } 
} 

Ausgabe

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

Aber was ich in Verfahren erhalten test1 ist nur ein Array mit Null-Elementen, sollte nicht der Ausdruck ArrayType[]::new ein Array mit der angegebenen Größe erstellen und die Konstruktion der Klasse A für jedes Element aufrufen, wie bei der Verwendung von e x Type::new in Methode test3?

Antwort

11

ArrayType[]::new ist eine Methodenreferenz zu einem Array-Konstruktor. Wenn Sie eine Instanz eines Arrays erstellen, werden die Elemente mit dem Standardwert für den Array-Typ initialisiert, und der Standardwert für Referenztypen ist null.

Wie new ArrayType[3] ein Array von 3 null Referenzen erzeugt, so s.apply(3) nicht ruft, wenn s Verfahren Verweis auf ein Array-Konstruktor (d.h. ArrayType[]::new) würde eine Anordnung von 3 null Referenzen erzeugen.

+0

Vielen Dank für Ihre ausführliche und klare Erklärung. Es war sehr hilfreich und verständlich. –

+1

@NarutoBijuMode Gern geschehen! – Eran

+3

Als Addendum kann die gewünschte Operation über 'test1 (3, i -> Stream.generate (A :: new) .limit (i) .toArray (A [] :: new)) erreicht werden;' – Holger