2012-04-13 6 views
3

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

class MyOuter 
{ 
    private int x= 10; 

    class MyInner 
    { 
     void dostuff(){ 
     System.out.println("The value of x is "+x); 
     } 
    } 
} 

В другом Java файл я создавать экземпляры для обоих MyOuter и MyInner классов, как показано ниже

Class Program 
{ 
    public static void main(String [] args) 
    { 
     MyOuter mo = new MyOuter(); 
     MyOuter.MyInner mi = mo.new MyInner(); 
     mi.dostuff(); 
    } 
} 

выше фрагмент кода компилирует прекрасно и дает выход из « значение x равно 10 ".

Что я хочу знать здесь, возникает ли конструктор, когда new() используется с классом MyInner и классом MyOuter. Если да, то есть ли какая-либо цепочка конструктора из внутреннего класса во внешний класс (например, конструктор надкласса для суперкласса и т. Д.).

ответ

8

Вы можете наблюдать конструктор цепи для внутреннего класса при расширении внутреннего класса.

Возьмем такой пример:

public class MainClass { 

    public MainClass(String value) { 
     System.out.println("mainValue: " + value); 
    } 

    public class NestedClass { 

     public NestedClass(String nestedValue) { 
      System.out.println("nestedValue: " + nestedValue); 
     } 
    } 

} 

, а затем продлить NestedClass как этот

public class NestedClassExtension extends NestedClass { 

    public NestedClassExtension(MainClass mainClass, String nestedValue) { 
     mainClass.super(nestedValue); 
    } 
} 

так что вы можете увидеть, что вы можете назвать супер конструктор вашего вложенного класса Попутно с этим конструктором MainClass и вызов .super на mainClass экземпляр объекта.

Теперь вы можете создавать экземпляры NestedClassExtension таким образом:

NestedClassExtension extension = new NestedClassExtension(new MainClass("main"), "nested"); 

Так что главный класс должен существовать, и его конструктор он называется первым. Тогда конструкторы вложенных классов.

Вместо если вы хотите создать экземпляр NestedClass снаружи из MainClass вы должны написать:

MainClass mc = new MainClass("main"); 
mc.new NestedClass("nested"); 

В другой раз MainClass должен быть создан первым, то вложенные классы.

3

Внутренний конструктор вызывается только когда у вас есть

MyOuter.MyInner mi = mo.new MyInner(); 

иначе он не будет даже вызывать конструктор внутреннего класса, как это не экземпляр, как статические блоки выполняются, но экземпляра блоки и конструкторы не не вызываются, пока вы создать объект.

2

Если вы не указали конструктор, создается default constructor, который не принимает параметров. Если вы объявляете какого-либо другого конструктора, скажите, что MyInner (int i) создается конструктор по умолчанию, и вам придется объявить его самостоятельно (при необходимости). Каждый объект (без каких-либо исключений) создается путем вызова конструктора.

2

Оба они создаются с использованием конструктора по умолчанию no-arg. В супер() наследования нет цепочки. Просто вы не можете создать экземпляр внутреннего класса без первого экземпляра внешнего класса.

Read the difference between static and non-static inner class.

1

Если скомпилировать предложил код, а затем запустить декомпилятор Java на нем

javap MyOuter$MyInner 

Вы бы видели, как компилятор на самом деле объявить конструктор для внутреннего класса:

public class MyOuter$MyInner extends java.lang.Object{ 
    final MyOuter this$0; 
    public MyOuter$MyInner(MyOuter); 
    void dostuff(); 
} 

Здесь вы можете см., что компилятор реализует ваш внутренний класс, объявляя конечный член поля, содержащий ссылку на охватывающий класс. Поле объявляется окончательным, и как таковое требуется предоставить значение для создания экземпляра вашего класса Inner.

Когда вы делаете MyOuter.MyInner mi = mo.new MyInner(), компилятор гарантирует, что экземпляр окружения передается как параметр.

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

Вы можете, тем не менее, построить цепочку конструктора между другими объявленными конструкторами вашего внутреннего класса.

Например, если такой код:

public class MyOuter 
{ 
    private int x= 10; 

    public class MyInner 
    { 
     private int y = 0; 

     public MyInner(){ 
      this(10); 
     } 

     public MyInner(int value){ 
      this.y = value; 
     } 

     void doStuff(){ 
      System.out.println("The value of x is "+x); 
     } 
    } 
} 

Здесь я цепные конструкторы жгутов внутренний класс.

Опять же, декомпилятор обеспечивает истолковать все это, чтобы убедиться, что внешний экземпляр передается в качестве параметра внутренней один:

public class MyOuter$MyInner extends java.lang.Object{ 
    final MyOuter this$0; 
    public MyOuter$MyInner(MyOuter); 
    public MyOuter$MyInner(MyOuter, int); 
    void doStuff(); 
}