java - 从Java中的构造函数调用抽象方法可以吗?

标签 java methods constructor virtual abstract

假设我有一个实现 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);
  }

}

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

基础构造函数 使用参数 1 创建的派生线程 导数使用参数 1 运行

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

最佳答案

这段代码演示了为什么您应该从不从构造函数调用抽象方法或任何其他可覆盖的方法:

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。这意味着构造函数中唯一的“安全”方法是私有(private)和/或 final方法。

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

关于java - 从Java中的构造函数调用抽象方法可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15327417/

相关文章:

c++ - 在 C++ 上的 if 语句中构造函数初始化后删除字符串

Javascript子类代码解释

用于真正大数据的 Java 图表库?

java - 在 Android 中授予线程低优先级

除非遇到换行符,否则 c++ 不会写入控制台

java - 如何使用父类(super class)调用方法

ruby - 创建允许 bang 和 non-bang 选项的方法

java - Spring MVC/Spring Roo 自定义 Controller ,以 JSON 形式返回 JPA 查询数据

java - 无法识别“.class”错误?

java - 错误 : celsius cannot be resolved to a variable