问题描述
让我们假设我有一个抽象的Base类来实现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();
}
这里是几个衍生类之一。
And here is one of a few derivative classes.
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:
基本构造函数
使用param创建的派生线程1
派生使用param 1运行
Base constructorDerivative thread created with param 1Derivative 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中的构造函数调用抽象方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!