Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否存在与嵌套类关联的构造函数_Java_Constructor_Inner Classes - Fatal编程技术网

Java 是否存在与嵌套类关联的构造函数

Java 是否存在与嵌套类关联的构造函数,java,constructor,inner-classes,Java,Constructor,Inner Classes,我想知道是否有任何构造函数涉及到内部类。例如,考虑下面给出的代码片段 class MyOuter { private int x= 10; class MyInner { void dostuff(){ System.out.println("The value of x is "+x); } } } 在另一个java文件中,我为MyOuter和MyInner类创建实例,如下所示 Class Program { publ

我想知道是否有任何构造函数涉及到内部类。例如,考虑下面给出的代码片段

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类一起使用时,是否调用构造函数。如果是,那么是否存在从内部类到外部类的任何构造函数链接(如子类调用超级类的构造函数等等)。

只有在

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

否则,它甚至不会调用内部类构造函数,因为它没有实例化,就像执行静态块一样,但在创建对象之前不会调用实例块和构造函数。

如果不指定构造函数,则创建一个不带参数的构造函数。如果您声明了任何其他构造函数,比如MyInner(inti),那么默认构造函数的创建是不允许的,您必须自己声明它(如果需要的话)。每个对象(没有任何异常)都是通过调用构造函数创建的。

它们都是使用默认的无参数构造函数实例化的。继承的super()中没有类似的链接。只是,如果不先实例化外部类,就不能实例化内部类


扩展内部类时,可以观察内部类的构造函数链

举个例子:

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
传递给该构造函数,并在
MainClass
对象实例上调用
.super

现在,您可以通过以下方式创建NestedClassExtension实例:

NestedClassExtension extension = new NestedClassExtension(new MainClass("main"), "nested");
所以主类必须存在,它的构造函数首先被调用。然后是嵌套类的构造函数

相反,如果要在
main类
之外创建
NestedClass
实例,则必须编写:

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

另一次,必须先创建
main类,然后创建嵌套类。

如果您编译建议的代码,然后在其上运行Java反编译器

javap MyOuter$MyInner
您将看到编译器实际上是如何为内部类声明构造函数的:

public class MyOuter$MyInner extends java.lang.Object{
    final MyOuter this$0;
    public MyOuter$MyInner(MyOuter);
    void dostuff();
}
在这里,您可以看到编译器通过声明包含对封闭类的引用的最终字段成员来实现内部类。该字段被声明为final,因此需要提供一个值来实例化
内部

执行
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();
}