2015-03-11 9 views
8

Esiste qualcosa di equivalente per StaticClass::new per la classe interna data l'istanza di classe esterna?Riferimento metodo costruttore per la classe interna (non statica)?

Edit:

Vale a dire se ho

class Outer { 
    class Inner { 
    } 
} 

posso fare Outer o = new Outer(); Inner i = o.new Inner() nella vecchia Java. Come posso esprimere lo o.new Inner() come riferimento di funzione.

+0

Potresti aggiungere del codice, ad esempio dove esattamente la classe è definita e dove vuoi usarla? –

+0

È interessante notare che nella sezione di esempio del [JLS sui riferimenti al metodo] (http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.13), esiste un esempio: 'Outer.Inner :: new' ma che non compila ... Forse intendevano' Outer.StaticNested :: new' ... – assylias

+0

Non un riferimento al metodo, ma potresti usare un lambda come '() -> outer.new Interno() ' –

risposta

8

Secondo la Oracle tutorials, ci sono quattro tipi di metodo riferimenti:

  • riferimento ad un metodo statico
    • ContainingClass::staticMethodName
  • riferimento ad un metodo di un oggetto particolare istanza
    • containingObject::instanceMethodName
  • riferimento ad un metodo di un oggetto arbitrario di un tipo particolare istanza
    • ContainingType::methodName
  • riferimento a un costruttore
    • ClassName::new

riferimenti a un locale/Le classi nidificate non sono elencate, quindi io wo Supponiamo che non sia supportato.

È possibile utilizzare il java.util.function.Supplier per attivare l'utilizzo di lambda al fine di ottenere un'istanza della classe annidata:

Outer outer = new Outer(); 
Supplier<Outer.Inner> supplier =() -> outer.new Inner(); 
0

Per la classe innestata statica, è possibile fare riferimento ad esso utilizzando classe esterna - OuterClass.NestedClass::new:

public class Main { 

    public static void main(String[] args) { 
     int[] array = {1, 2, 3}; 

     Arrays.stream(array).forEach(A.B::new); 
    } 

} 

class A { 

    public A(int x) { 
     System.out.println("A created, x = " + x); 
    } 

    public static class B { 

     public B(int x) { 
      System.out.println("B created, x = " + x); 
     } 

    } 

} 

Per classe interna (classe non statica nidificato), si può fare outerInstanceName.new InnerClass(...):

public class Main { 

    public static void main(String[] args) { 
     int[] array = {1, 2, 3}; 

     A a = new A(500); 

     Arrays.stream(array).forEach(x -> a.new B(x)); 
    } 

} 

public class A { 

    public A(int x) { 
     System.out.println("A created, x = " + x); 
    } 

    public class B { 

     public B(int x) { 
      System.out.println("B created, x = " + x); 
     } 

    } 

} 

Il mio IDE mi suggerisce di convertire x -> a.new B(x) in A.B::new, ma questo non viene compilato, perché B non è statico - non appartiene alla classe A ma all'istanza della classe A. Quindi, rispondendo alla tua domanda, penso che non sia possibile e dovrai usare outerInstanceName.new InnerClass(...).

2

Il Chapter 15.13. Method Reference Expressions nel JLS contiene una dichiarazione un po 'criptica su questo:

L'istanza immediatamente allegata di una nuova istanza di classe interna (§15.9.2) viene fornita da un'istanza che include lessicamente this (§8.1.3).

Ciò significa che un metodo di riferimento al costruttore di una classe interna è possibile in un metodo della classe esterna, come in questo esempio

import java.util.function.Supplier; 
class Outer 
{ 
    public class Inner 
    { 
    } 
    void example() 
    { 
     Supplier<Inner> s = Inner::new; 
    } 
} 

Ma il JLS non menziona alcun In alternativa, si deve supporre che semplicemente non sia possibile fornire l'istanza allegata in nessun'altra forma che non sia this.

+0

Bello. È praticamente lo stesso motivo per cui è possibile eseguire 'new Inner()' solo nella classe di chiusura. :) –

Problemi correlati