【问题标题】:what is the difference in the behavior of this code?这段代码的行为有什么区别?
【发布时间】:2017-01-09 02:38:55
【问题描述】:

我有以下代码:

public class Application extends ApplicationManager{

    public static void main(String[] args) {
        ProcessUtility.enableProcessUtility(); 
        new Application().start();
    }
}

以及ApplicationManager类的代码:

public class ApplicationManager {

public ApplicationManager() {

   String configPath = "file:home" +  File.separator + "log4j.xml";
   System.setProperty("log4j.configuration", configPath);
   logger = Logger.getLogger(ApplicationManager.class);
 }

protected void start() {
    logger.info("*** Starting ApplicationManager ***");
}

我在运行应用类的时候会调用父类的start方法,不调用父类默认构造函数可以调用吗?

我的第二个问题是上面的代码与这段代码不同:

public class Application extends ApplicationManager{

    public static void main(String[] args) {    
        new Application().start();
    }


    @Override
    protected void start() {
        ProcessUtility.enableProcessUtility();
        super.start();
    }
}

和上面的 ApplicationManager 类。

这是静态方法的代码:

public static void enableProcessUtility() {
    isCommon = false;
}

提前致谢。

【问题讨论】:

    标签: java methods polymorphism overriding super


    【解决方案1】:

    调用非静态方法(您的start 方法)需要创建包含该方法(或该类的子类)的类的实例。创建类的实例需要调用该类及其所有祖先类的构造函数。因此,您无法避免执行父级默认构造函数。

    至于第二个问题,将ProcessUtility.enableProcessUtility()移动到子类的start方法中意味着每次调用start方法都会执行。

    也就是说,在您的示例中,您的 main 仅创建一个 Application 实例,并且只为该实例调用一次 start。因此ProcessUtility.enableProcessUtility() 只会在两个 sn-ps 中执行一次,并且行为是相同的。

    编辑:两个 sn-ps 之间的另一个区别是,第一个 sn-p 在创建 Application 实例之前调用 ProcessUtility.enableProcessUtility(),而第二个 sn-p 首先创建实例,然后从内部调用 ProcessUtility.enableProcessUtility()子类的start。如果构造函数(子类或超类)的行为受到对ProcessUtility.enableProcessUtility() 的调用的影响,则两个 sn-ps 可能会产生不同的输出。

    【讨论】:

    • 当我运行这两个代码时,我得到了不同的结果怎么会发生这种情况?,我知道它必须调用父构造函数,但是父构造函数的某些代码没有在这些实现之一中运行!
    • @flashDisk 在第二个 sn-p 中,构造函数在 ProcessUtility.enableProcessUtility() 之前执行。也许这就是导致不同行为的原因。
    • 正确的行为是第二​​种实现,但我仍然找不到原因!
    • @flashDisk 如果没有看到构造函数的代码ProcessUtility.enableProcessUtility()start(),我无法回答这个问题。
    • 代码已更新,不同之处在于,在一种实现中,log4j 将上述行打印到控制台,而在第二种实现中则没有!。
    【解决方案2】:

    您的第一个问题在这里得到解答https://stackoverflow.com/a/10508202/2527075

    关于你的第二个问题,超级构造函数将在第二个示例中的 ProcessUtility 调用之前调用,而在第一个示例中 ProcessUtility 调用首先出现。

    【讨论】:

    • 什么时候调用父类的构造函数?,什么时候调用它的方法之一?还是在调用子类的构造函数时?
    • 每个构造函数首先执行一个隐式 super();称呼。所以每个子类的构造函数都会先调用超级构造函数。
    猜你喜欢
    • 1970-01-01
    • 2020-01-04
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    • 2012-09-22
    • 2011-10-31
    • 1970-01-01
    相关资源
    最近更新 更多