当前位置: 首页 > 面试题库 >

从Java的构造函数中调用抽象方法是否可以?

秦晋
2023-03-14
问题内容

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

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创建的派生线程使用参数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完成初始化之前执行。



 类似资料:
  • 用参数1导数创建的基构造函数导数线程正在用参数1运行 但是在JAVA中启动一个线程调用构造函数中的抽象方法安全吗?因为,就我所知,在C++和C#中,它在大多数情况下是不安全的。谢谢!

  • 问题内容: 对不起任何较小的语法错误或其他错误,我正在使用Jitsi模块进行此操作,并且对Java不太熟悉,因此想确认正在发生的事情以及为什么以及如何对其进行修复。 使用按名称加载类方法创建类B的实例时,应用程序正在执行此操作: 在类B中调用重写的load() 初始化变量(根据调试器调用“私有字符串testString = null”),将其无效。 这是预期的Java行为吗?是什么原因造成的?它是

  • 问题内容: 抽象类可以有构造函数吗? 如果是这样,它将如何使用以及用于什么目的? 问题答案: 是的,抽象类可以具有构造函数。考虑一下: 超类是抽象的,并且具有构造函数。具体的类具有仅对值2进行硬编码的构造函数。具体的类具有允许调用者指定值的构造函数。 抽象构造函数将经常用于强制类约束或不变量,例如设置类所需的最小字段。

  • 问题内容: 我遇到的情况是,在实例化类时,我只想读取配置文件一次。 假设我有一个名为的方法,该方法读取配置并将其放入对象中。当程序需要使用配置值时,它将使用定义键读取对象。我想知道构造函数仅在生命周期中调用一次。我可以将我的方法放入构造函数中,这将使我有一次调用的好处,还是有另一种机制可以这样做? 问题答案: 更好的设计是 工厂设计模式

  • 我是新爪哇,目前正在大学读一门课程。我们使用Java编程早期对象作为课程文献。我有一个关于新对象构造函数的问题。这本书非常明确地指出,“即使这样做是可能的,也不要从构造函数调用方法。” 这是所有的方法吗,句号?我理解从构造函数调用类自己的实例方法的问题。但是帮手方法等? 这可以接受吗?如果没有,我想你不能在构造函数中使用任何Java数学util函数或类似的东西?

  • 问题内容: 我有这样的事情: 如您所见,超类的init方法是抽象的,并在创建对象后由构造函数自动调用。 当我需要创建这种类型的对象且其结构不会及时更改时,我很好奇我是否会遇到这样的代码问题。 有什么更好的办法吗?它可以在Java中运行,但是可以在C ++和ActionScript中运行吗? 谢谢你的答案。 问题答案: 请勿从构造函数中调用过多的方法。 引用 有效Java 2nd Edition,条