2015-03-11 3 views
8

Есть ли что-то эквивалентное для StaticClass::new для внутреннего класса с учетом экземпляра внешнего класса?Ссылка на конструктор-метод для (нестатического) внутреннего класса?

Редакция:

I.e. если у меня есть

class Outer { 
    class Inner { 
    } 
} 

я могу сделать Outer o = new Outer(); Inner i = o.new Inner() в старом Java. Как я могу выразить o.new Inner() как функцию ссылки.

+0

Не могли бы вы добавить код, т. Е. Где именно определен класс и где вы хотите его использовать? –

+0

Интересно, что в разделе примеров [JLS по методам ссылок] (http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.13) есть Например: 'Outer.Inner :: new', но это не компилируется ... Они, возможно, означают' Outer.StaticNested :: new' ... – assylias

+0

Не ссылка на метод, но вы можете использовать лямбда как '() -> external.new Inner() ' –

ответ

8

Согласно Oracle tutorials, существует четыре вида ссылок Метод:

  • Ссылка на статический метод
    • ContainingClass::staticMethodName
  • Ссылка на метод экземпляра конкретного объекта
    • containingObject::instanceMethodName
  • Ссылка на метод экземпляра произвольного объекта определенного типа
    • ContainingType::methodName
  • Ссылка на конструктор
    • ClassName::new

Ссылки на местный/вложенный класс не указаны, поэтому я wo uld предполагает, что он не поддерживается.

Вы можете использовать java.util.function.Supplier, чтобы вызвать использование лямбды для того, чтобы получить экземпляр вложенного класса:

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

Для статического вложенного класса, вы можете обратиться к нему с помощью внешнего класса - 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); 
     } 

    } 

} 

Для внутреннего класса (вложенный не статический класс), вы можете сделать 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); 
     } 

    } 

} 

Моя IDE предлагает мне преобразовать x -> a.new B(x) в A.B::new, но это не скомпилируется, потому что B не является статическим - он принадлежит не классу A, а экземпляру класса A. Поэтому, отвечая на ваш вопрос, я думаю, что это невозможно, и вам нужно будет использовать outerInstanceName.new InnerClass(...).

2

Chapter 15.13. Method Reference Expressions в JLS содержит несколько загадочное заявление об этом:

Прилагаемый экземпляр нового экземпляра внутреннего класса (§15.9.2) предоставляется лексически охватывающим экземпляром this (§8.1.3).

В основном это означает, что эталонный метод конструктору внутреннего класса можно в метод внешнего класса, как в этом примере

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

Но JLS не говоря уже о какой-либо альтернативно, поэтому нужно предположить, что просто невозможно предоставить охватывающий экземпляр в любой другой форме, кроме this.

+0

Nice one. Это почти та же причина, по которой вы можете делать 'new Inner()' только внутри класса. :) –

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