当前位置: 首页 > 知识库问答 >
问题:

初始化“最终”实例变量

乐正涵忍
2023-03-14

我想了解各种情况下类实例的初始化
在JLS-7第12.5节中,没有提到如何以及何时初始化最终实例变量?如果实例变量被声明为final,是否有人能给我一点参考来理解其行为?

   public class Test {

        public static void main(String args[]){

            Child  c1 = new Child();
        }
    }

    class Parent{
        final int a =30;
        Parent(){
            System.out.println("From super Contsrutor "+a);
            meth();
        }
        void meth(){
             System.out.println("From super");
        }
    }

    class Child extends Parent{
         final  int e=super.a;
         int b=30;
        void meth(){
            System.out.println("From Sub e=" +e+", b="+b);
        }
    }

给出的输出如下

From super Contsrutor 30
From Sub e=0,b=0

在哪里作为

public class Test {

    public static void main(String args[]){

        Child  c1 = new Child();
    }
}

class Parent{
    final int a =30;
    Parent(){
        System.out.println("From super Contsrutor "+a);
        meth();
    }
    void meth(){
         System.out.println("From super");
    }
}

class Child extends Parent{
     final  int e=a;
    void meth(){
        System.out.println("From Sub " +e);
    }
}

是否将输出作为

From super Contsrutor 30
From Sub 30

共有3个答案

咸亦
2023-03-14

让我们找出程序的流程,我写了下面的代码:

package com.test;

public class Test {

    public static void main(String args[]) {
        Child c1 = new Child();
    }
}

class Parent {
    final int a = 30;
    static int count = 0;
    {
        System.out.println("Parent initialization block " + ++count);
    }
    Parent() {
        System.out.println("Parent constructor " + ++count);
        // System.out.println("From super Contsrutor " + a);
        meth();
    }
    void meth() {
        // System.out.println("From super");
        System.out.println("Parent meth method " + ++count);
    }
}

class Child extends Parent {
    final int e = super.a;
    int b = 30;
    {
        System.out.println("Child initialization block " + ++count);
    }
    public Child() {
        System.out.println("Child constructor " + ++count);
    }
    void meth() {
        System.out.println("Child meth method " + ++count);
        // System.out.println("From Sub e=" + e + ", b=" + b);
    }
}

输出:

Parent initialization block 1
Parent constructor 2
Child meth method 3
Child initialization block 4
Child constructor 5

首先,请记住,我已经为类编写了初始化块,它在构造函数之前被调用。

现在,如果您可以从创建Child对象时的输出中看到,首先Parent类被加载到内存中,然后您调用了meth方法,在Parent构造函数中调用meth方法Child类,但是Child但是此时没有调用初始化块和Child构造函数,这意味着此时b没有初始化为30,而是初始化为int默认值值0,与e变量的情况相同。

葛晔
2023-03-14

第一段代码给出如下输出

From super Contsrutor 30
From Sub e=0,b=0

这是因为下面的原因。

当我们执行new Childs()时,Childclass的构造器开始执行

但它的第一个语句默认为super,因此它调用父类构造函数

现在父类构造函数有以下代码

父(){System.out.println("来自超级联系人"a);冰毒();}

所以这里父类调用meth()方法,它的调用方实际上是子类child的对象,所以它调用子类meth()方法。

现在,当它从super Constructor调用子类meth()方法时,实际上子对象尚未创建,因此其变量尚未初始化,但我们正在打印a和b的值。

因此,在子构造函数完成执行之后,b在分配之前得到0。

因此,像下面这样更改第一段代码将得到所需的输出,即将meth()调用放在子构造函数中,而不是放在父构造函数中。

package com.kb.finalVariables;

public class Test {

    public static void main(String args[]){

        Child  c1 = new Child();
    }
}

class Parent{
    final int a =30;
    Parent(){
        System.out.println("From super Contsrutor "+a);
       // meth();
    }
    void meth(){
         System.out.println("From super");
    }
}

class Child extends Parent{

     final  int e=super.a;
     int b=30;
     public Child() {
        meth();
    }
    void meth(){
        System.out.println("From Sub e=" +e+", b="+b);
    }
}
陶烨赫
2023-03-14

这个啊

final int e = a;

是一个常量变量,一个常量表达式。在调用中

System.out.println("From Sub e=" +e+", b="+b);

编译器可以将e的使用替换为其值30

在里面

final int e = super.a;

变量e不是常量变量,因为super。a不是简单的名称,因此该值不能也不会被替换。

 类似资料:
  • 问题内容: 来自Sun文档 通常,您需要将代码放在构造函数中以初始化实例变量。 使用构造函数初始化实例变量有两种选择:初始化块和final方法。 我能理解初始化块的用法。谁能解释一下实例初始化方法的最终方法吗?非最终公开赛员可以完成这项工作。为什么不只是使用它们呢? 问题答案: 您链接到的同一Sun教程中已经描述了该优点: 最终方法不能在子类中覆盖。 有关接口和继承的课程将对此进行讨论。 非最终方

  • 下面的示例类无法编译: 此代码的编译错误消息是: 但是,对于包含以下方法的类,Java不会生成任何错误消息: 关于初始化及其要求,为什么Java对最终实例变量和最终局部变量的处理不同?谢谢

  • 本文向大家介绍tensorflow 初始化未初始化的变量实例,包括了tensorflow 初始化未初始化的变量实例的使用技巧和注意事项,需要的朋友参考一下 今日在Stack Overflow上看到一个问如何只初始化未初始化的变量,有人提供了一个函数,特地粘贴过来共大家品鉴: 通过tf.global_variables()返回一个全局变量的列表global_vars, 然后以python列表解析式的

  • 问题内容: 这是一些示例代码, 输出:d.value()返回0 //我希望10是因为lookup()被覆盖,但不是0!有人可以澄清吗? 的实例变量的初始化在执行其查找方法时尚未发生。如何确保在调用其方法时初始化的实例变量? 问题答案: 首先,由于缺乏方法,该代码无法编译。 无论如何,我相信您的问题是,由于构造函数是分层运行的,您的期望是无效的。 超类的构造函数始终在子类的构造函数之前运行,这包括子

  • 问题内容: 我们如何在对象创建时初始化类的最终变量? 任何人都可以解释它怎么可能?… 问题答案: 您必须一次且仅一次初始化最终变量。有三种方法可以对实例变量执行此操作: 在构造函数中 在实例初始化块中。 当你声明它 这是这三个示例: 在每种情况下,代码在您调用时都运行一次,并且无法再次调用其中的任何一个,这满足了初始化要求每个实例仅执行一次的要求。

  • 问题内容: 我不断遇到Java问题的细微变化,并且这个问题开始浮现,我真的想不出解决该问题的合适方法。 我有一个最终的但动态的对象属性。也就是说,我希望该值一旦分配便是恒定的,但该值在每个运行时可以不同。因此,我在课程开始时声明了课程级别变量-say 。然后,在构造函数中,给它分配一个值-说 当我的方法中有引发异常的代码时,问题就开始了。所以我在构造函数中尝试这样的事情: 现在我有一个错误-“空白