在Java中从构造函数调用抽象方法可以吗? [英] Is it OK to call abstract method from constructor in Java?

查看:27
本文介绍了在Java中从构造函数调用抽象方法可以吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个实现 Runnable 接口的抽象基类.

Let's suppose I have an abstract Base class that implements Runnable interface.

public abstract class Base implements Runnable {

  protected int param;

  public Base(final int param) {
      System.out.println("Base constructor");
      this.param = param;
      // I'm using this param here
      new Thread(this).start();
      System.out.println("Derivative thread created with param " + param);
  }

  @Override
  abstract public void run();
}

这是少数派生类之一.

public class Derivative extends Base {

  public Derivative(final int param) {
      super(param);
  }

  @Override
  public void run() {
      System.out.println("Derivative is running with param " + param);
  }

  public static void main(String[] args) {
      Derivative thread = new Derivative(1);
  }

}

关键是我希望我的基类做一些通用的事情,而不是每次都复制它.实际上,它运行良好,输出始终相同:

The point is that I want my Base class do some general stuff instead of copying it every time. Actually, it's running fine, the output is always the same:

基础构造函数使用参数 1 创建的衍生线程Derivative 以参数 1 运行

Base constructor Derivative thread created with param 1 Derivative is running with param 1

但是在 JAVA 中启动一个线程调用构造函数中的抽象方法是否安全?因为,据我所知,在 C++ 和 C# 中,在大多数情况下它是不安全的.谢谢!

But is it safe IN JAVA to start a thread calling the abstract method in constructor? Because, in C++ and C# it is unsafe in most cases, so far as I know. Thank you!

推荐答案

这段代码说明了为什么你应该永远从构造函数中调用抽象方法或任何其他可覆盖的方法:

This code demonstrates why you should never call an abstract method, or any other overridable method, from a constructor:

abstract class Super {
    Super() {
        doSubStuff();
    }
    abstract void doSubStuff();
}

class Sub extends Super {
    String s = "Hello world";

    void doSubStuff() {
        System.out.println(s);
    }
}

public static void main(String[] args) {
    new Sub();
}

运行时,打印null.这意味着构造函数中唯一的安全"方法是私有和/或最终方法.

When run, this prints null. This means the only "safe" methods to have in a constructor are private and/or final ones.

另一方面,您的代码实际上并未从构造函数调用抽象方法.相反,您将一个未初始化的对象传递给另一个线程进行处理,这更糟糕,因为您启动的线程可能会被赋予优先级并在您的 Base 完成其初始化之前执行.

On the other hand, your code doesn't actually call an abstract method from a constructor. Instead, you pass an uninitialized object to another thread for processing, which is worse, since the thread you're starting may be given priority and execute before your Base finishes its initialization.

这篇关于在Java中从构造函数调用抽象方法可以吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆