java中的对象是否在调用构造函数之前在堆上创建?

java中的对象是否在调用构造函数之前在堆上创建?,java,inheritance,constructor,heap,Java,Inheritance,Constructor,Heap,当从基类的构造函数调用重写的方法时,也会根据运行时多态性概念调用子类中定义的方法。我想知道在JVM中如何处理这个问题,当控件位于基类构造函数中时,子类的构造函数还没有被调用,因此对象还没有完全构造 我了解从基类构造函数调用重写方法的不良影响,但我只想了解这是如何实现的 我觉得堆中的对象是在调用构造函数之前创建的,当调用构造函数时,属性被初始化。请为上述内容提供宝贵的意见 下面是演示相同功能的代码 Base.java public class Base { public Base() {

当从基类的构造函数调用重写的方法时,也会根据运行时多态性概念调用子类中定义的方法。我想知道在JVM中如何处理这个问题,当控件位于基类构造函数中时,子类的构造函数还没有被调用,因此对象还没有完全构造

我了解从基类构造函数调用重写方法的不良影响,但我只想了解这是如何实现的

我觉得堆中的对象是在调用构造函数之前创建的,当调用构造函数时,属性被初始化。请为上述内容提供宝贵的意见

下面是演示相同功能的代码

Base.java

public class Base {
    public Base() {
            System.out.println("Base constructor is executing...");
            someMethod();
    }

    public void someMethod() {
            System.out.println("someMethod defined in Base class executing...");
    }
}
public class Sub extends Base{
    public Sub() {
            System.out.println("Sub constructor is executing...");
    }
    @Override
    public void someMethod() {
            System.out.println("someMethod defined in Sub class executing...");
    }
}
public class Client {
    public static void main(String[] args) {
            Sub obj = new Sub();
    }
}
Sub.java

public class Base {
    public Base() {
            System.out.println("Base constructor is executing...");
            someMethod();
    }

    public void someMethod() {
            System.out.println("someMethod defined in Base class executing...");
    }
}
public class Sub extends Base{
    public Sub() {
            System.out.println("Sub constructor is executing...");
    }
    @Override
    public void someMethod() {
            System.out.println("someMethod defined in Sub class executing...");
    }
}
public class Client {
    public static void main(String[] args) {
            Sub obj = new Sub();
    }
}
Client.java

public class Base {
    public Base() {
            System.out.println("Base constructor is executing...");
            someMethod();
    }

    public void someMethod() {
            System.out.println("someMethod defined in Base class executing...");
    }
}
public class Sub extends Base{
    public Sub() {
            System.out.println("Sub constructor is executing...");
    }
    @Override
    public void someMethod() {
            System.out.println("someMethod defined in Sub class executing...");
    }
}
public class Client {
    public static void main(String[] args) {
            Sub obj = new Sub();
    }
}
控制台上的输出为

基本构造函数正在执行

子类中定义的someMethod正在执行

子构造函数正在执行

java中的对象是否在调用构造函数之前创建

是的,否则您将没有要初始化的对象

在字节码级别,首先创建对象,然后调用构造函数,传入要初始化的对象。构造函数的内部名称为
,其返回类型始终为
void
,这意味着它不返回对象,只对其进行初始化


注意:
不安全。allocateInstance
将在不调用构造函数的情况下创建对象,并且对于反序列化非常有用。

简短的回答是肯定的。使用
dup
opcode创建新的对象实例,之后只调用构造函数。您也可以在不调用构造函数的情况下创建自己的对象,例如使用反序列化。@nits.kk,请参阅本文:相关参考:
新对象包含指定类类型及其所有超类中声明的所有字段的新实例。创建每个新的字段实例时,都会将其初始化为默认值(§4.12.5)。
@nits.kk对
final
字段执行此操作,但是检查非final字段意味着检查类的使用方式,这要复杂得多,可能无法解决。e、 g.您必须检查在所有可能的代码路径中,字段的setter是否在getter之前被调用。@nits.kk局部变量仅“存在”,从它们第一次被赋值到它们在其中声明的块结束。每次有人调用该方法时,他们都会看到自己的局部变量值。而字段从对象创建到收集都存在,每个人都看到相同的字段。(虽然在多线程上下文中不总是相同的值,但这是完全不同的蠕虫。)但理论上,局部变量也可以自动初始化为
null
0
false
,我们刚刚决定不会这样做。@biziclop如果编译器/IDE能够检测到不安全的线程访问并自动修复,我想我们将失业。;)@彼得·拉维:哈哈,很有可能。:)不,我的意思是相反的,他们可以决定不检查局部变量是否总是在读取之前写入,而只是在声明时将它们初始化为默认值。不过情况会更糟。