Java 父类可以创建其子类的实例吗?

Java 父类可以创建其子类的实例吗?,java,inheritance,sonarqube,Java,Inheritance,Sonarqube,我用Sonarqube在一些Java代码上运行了单元测试,我发现的问题之一如下 类在初始化期间不应访问自己的子类 当父类在其自己的初始化过程中引用子类的成员时,结果可能不是您期望的结果,因为子类可能尚未初始化。这可能会造成所谓的“初始化周期”,甚至在某些极端情况下造成僵局 这是用于描述问题的示例代码: class Parent { static int field1 = Child.method(); // Noncompliant static int field2 = 42;

我用Sonarqube在一些Java代码上运行了单元测试,我发现的问题之一如下

类在初始化期间不应访问自己的子类

当父类在其自己的初始化过程中引用子类的成员时,结果可能不是您期望的结果,因为子类可能尚未初始化。这可能会造成所谓的“初始化周期”,甚至在某些极端情况下造成僵局

这是用于描述问题的示例代码:

class Parent {
  static int field1 = Child.method(); // Noncompliant
  static int field2 = 42;

  public static void main(String[] args) {
    System.out.println(Parent.field1); // will display "0" instead of "42"
  }
}

class Child extends Parent {
  static int method() {
    return Parent.field2;
  }
}
接下来是提出问题的代码的简化

abstract class Parent {
    static Parent childInstance = new Child();
}
我真的不明白为什么这是一个问题。在Sonarqube示例中,父级通过调用子级的静态方法初始化
field1
。这意味着在调用该方法之前,我不需要实例化子对象

在第二段代码中,父级尝试实例化子级,而不是调用其方法之一

你能给我解释一下为什么不能在父类中提及孩子吗


编辑:我正在使用SonarScanner for Maven,我的Sonarqube版本是8.4.1.35646。问题的规则id是S2390。

请考虑在此处执行代码的时间:

abstract class Parent {
    static Parent childInstance = new Child();
}
由于您分配给一个
静态
字段,因此在创建第一个
实例之前,必须执行
新子(

即在类初始化期间(为了简单起见,让我们假设这相当于“类加载”,尽管这并不十分准确)

这意味着,当类
父类
被初始化时,它会创建一个
子类
的新实例。通常,要完成初始化,首先需要做的事情之一是超类已经初始化。由于我们当前正在初始化
Parent
,我们可以知道
Child
无法完全初始化(根据定义,这需要
Parent
完全初始化)

JVM/Java语言规范使用了一些“技巧”来实际允许此构造工作,但它们也有缺点(例如能够观察未初始化的
final
字段)


这样想:当你忙于建造地下室时,你正试图从房子的第二层抓取一些东西。

想想这里何时执行代码:

abstract class Parent {
    static Parent childInstance = new Child();
}
由于您分配给一个
静态
字段,因此在创建第一个
实例之前,必须执行
新子(

即在类初始化期间(为了简单起见,让我们假设这相当于“类加载”,尽管这并不十分准确)

这意味着,当类
父类
被初始化时,它会创建一个
子类
的新实例。通常,要完成初始化,首先需要做的事情之一是超类已经初始化。由于我们当前正在初始化
Parent
,我们可以知道
Child
无法完全初始化(根据定义,这需要
Parent
完全初始化)

JVM/Java语言规范使用了一些“技巧”来实际允许此构造工作,但它们也有缺点(例如能够观察未初始化的
final
字段)


可以这样想:当你忙于建造地下室时,你正试图从房子的第二层抓取一些东西。

什么是sonarqube版本?还有,你能分享规则id吗?@lkamal当然我编辑了这个问题。sonarqube的版本是什么?另外,你能分享规则id吗?@lkamal当然我编辑了这个问题。