JAVA构造函数里调用抽象方法_在Java中从构造函数调用抽象方法可以吗?

本文探讨了在Java中从构造函数调用抽象方法的实践及其潜在风险。通过示例代码,作者指出尽管代码可以正常运行,但这种做法并不推荐。在构造函数中调用的方法应为私有或最终方法,以避免重写导致的问题。此外,将未完全初始化的对象传递给新线程可能导致线程安全问题和未定义的行为。建议避免在构造函数中直接调用可能依赖于对象状态的方法。
摘要由CSDN通过智能技术生成

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

假设我有一个实现了Runnable接口的抽象Base类。

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); } }

关键是,我希望我的基类做一些一般的东西,而不是每一次复制它。 其实它运行的很好,输出总是一样的:

基础构造函数使用参数1 Derivative创build的衍生线程使用参数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 。 这意味着构造函数中唯一的“安全”方法是私有的和/或最终的。

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

从构造函数调用抽象方法是一个非常糟糕的做法。 从构造函数调用的方法应始终是私有的或最终的,以防止重写。

在这里看到这个链接到一个问题

从run()被调用时,不是一个好主意,Derivative对象可能没有被初始化。 如果run()取决于Derivative中的任何状态,则可能会失败。

在你的简单情况下,它的作品。 但是这个子类没有意义。 你可以简单

public Base(final int param, Runnable action) { new Thread(action).start();

把this从构造函数中传递出来叫做“让它从构造函数中转义出来”,并且会导致一些特别讨厌和怪异的错误,因为这个对象可能处于不一致的状态。

这是特别的情况下, this是传递给另一个线程,如在这个例子中。 由于JVM有权对线程中的语句进行重新sorting,因此可能会发生未定义的行为/状态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值