繁体   English   中英

最终字段的初始化

[英]Initialization of final fields

有人可以向我解释此示例的行为:

package test;

public class Test {

    static abstract class Parent{

        public Parent() {
            print();
        }
        public abstract void print();
    }

    static class Child extends Parent{

        protected final int i= 10;

        public Child() {
            super();
        }
        public void print(){
            System.out.println(i);
        }
    }

    public static void main(String[] args) {
        System.out.println("Test");
        new Child();

    }

}

此代码段的输出为10 但是,当我将变量i更改为任何对象(例如Integer)时,输出为null 但是,当我改变静态整数输出为10预期。

我认为,在调用任何方法(或构造函数)之前都要先初始化字段,但是这里这种方法仅适用于原始类型,而不适用于对象。

谢谢

拉迪姆

类的实例字段是在构造函数中的super()调用之后直接初始化的,无论它们是否为最终值。 但是, super()调用父级的类构造函数,该构造函数读取因此未初始化的字段的值。

上课的时候在运行时,这意味着一类的构造函数被调用(在之前之前静态字段initilized引用类的静态字段都被初始化super()在类的构造函数调用)。

当字段类型为int时,为什么仍打印10的原因是,Java编译器可以在编译时内联最后字段的值。 在那种情况下,程序永远不会读取该字段的值,因为编译器优化了代码,使其看起来像System.out.println(10)而不是System.out.println(i) 在这种情况下,Java编译器不会内联最后字段,但是,对于原始字段类型很可能这样做,而对于大多数对象类型则不太可能。

非静态成员:

new Child()以此顺序触发构造函数链接Parent()-> Child()。

当父对象被实例化时,您正在调用print(),因为它持有子对象的引用,它将调用

public void print(){
            System.out.println(i); 
        }

因为在这个阶段,孩子的启蒙还没有完成。 整数i没有任何值,因此它将输出null

静态变量:

一旦引用/调用了相应的类, Static data member被初始化,因此它将打印10

调用父构造函数时,子实例的实例字段未初始化

这是因为逻辑上,应该在Child存在之前Parent应该存在。

因此,首先调用Parent的构造函数,在此期间, 不会初始化Child任何字段。

因此,当您调用 Child 覆盖print()时,将print() i的未初始化值。

静态字段在类初始化时初始化

类加载期间发生的类初始化时进行初始化,因此它们将具有初始化的值

由于字段的最终性质,与变量不同,它在构造函数之前初始化。 因此,将打印该值。

当您声明final Integer i = 10时会发生什么? 或者int i = 10

主代码应为

Child child = new Child();
child.print();

然后,如果使用int或Integer,则返回10;否则,返回10。

仅使用

new Child()

则此变量没有返回值,并且新实例被忽略。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM