【问题标题】:Why does instantiating a class output the class's contents?为什么实例化一个类会输出类的内容?
【发布时间】:2017-04-26 18:39:15
【问题描述】:

我正在学习继承,并且正在使用这个简单的程序,它有一个超类和一个子类,如下所示。我的问题不是针对这个程序的。然而,这是我第一次看到这种情况发生的地方,所以我用它作为一个更一般的概念问题的例子。

为什么简单地实例化类会运行构造函数并输出内容? 我之前的理解是,实例化类只是创建对象,但它不会做任何事情。

SuperClass1.java

public class SuperClass1 {
            public SuperClass1(){        
                System.out.println("This is the superclass constructor.");
            }
        }

SubClass2.java

public class SubClass2 extends SuperClass1
{
    public SubClass2()
    {
        System.out.println("This is the subclass constructor.");
    }

}

Main.java

public class Main {

    public static void main(String[] args)
    {
        SubClass2 obj1 = new SubClass2(); // why should this print something?
    }
}

输出
这是超类的构造函数。
这是子类的构造函数。

【问题讨论】:

  • “实例化类”通常意味着做某事。除了将每个字段设置为 0(或 null 或 false)之外,Java 本身并不真正知道如何做任何事情。大多数时候这还不够,所以类在实例化时必须真正做一些事情。在您的情况下,“实例化”恰好包含println
  • 因为它是这样工作的。我建议阅读 Oracle Java 教程,因为那里解释了所有基本内容。

标签: java object inheritance printing instantiation


【解决方案1】:

首先,实例化一个对象意味着调用(并执行)构造函数,这就是它的用途。

所以,这个:

SubClass2 newInstance = <createNewInstance>;
newInstance.<init()>;

都是由 Java 中的构造函数调用 new SubClass2() 完成的。 “构造”对象和“初始化”其属性之间没有区别。

此外,如果您没有显式调用超类的另一个构造函数,则在创建类的对象时会自动调用默认构造函数(没有参数的构造函数)。因此,实例化子类的对象调用超类构造函数(打印第一行),然后自己打印第二行。

更详细地说,子类在幕后看起来像这样:

public class SubClass2 extends SuperClass1
{
    public SubClass2()
    {
        super();   // calls the superclass constructor
        System.out.println("This is the subclass constructor.");
    }
}

【讨论】:

  • geeksforgeeks.org/g-fact-67 这看起来与您的示例非常相似,并添加了一个带有参数化构造函数的示例。
  • 谢谢!这完美地回答了我试图理解的内容!
  • @MalteHartwig 加载和实例化类时,不需要调用构造函数。当你构造一个对象时,它会使用构造函数进行初始化,但初始化类时不涉及构造函数。
  • @P.J.Meisch 你是对的,我混合了类/对象和实例化/初始化。我已经修改了我的答案以使用正确的术语。
【解决方案2】:

因为你调用的构造函数包含打印语句。

您调用构造函数方法 SubClass2(),其中包含打印语句。

【讨论】:

    【解决方案3】:

    打印语句不是因为类被加载,而是因为该类的一个对象被实例化并且构造函数被调用:

    可以不使用构造函数来加载类,如下代码所示:

    public class Test {
    
        public static void main(String[] args) {
            try {
                Class.forName("Test$Inner");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    
        static class Inner {
            static {
                System.out.println("static initializer");
            }
            public Inner() {
                System.out.println("inner ctor");
            }
        }
    }
    

    运行该程序表明只调用了静态类初始化程序,而没有调用构造函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-07
      • 1970-01-01
      • 2020-11-30
      • 2016-11-12
      • 1970-01-01
      相关资源
      最近更新 更多