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

实例变量初始化中的问题

弘和同
2023-03-14
问题内容

这是一些示例代码,

class Base
{
  private int val;

  Base() {
  val = lookup();
  }

  public int lookup() {
    //Perform some lookup
  // int num = someLookup();
  return 5;
  }

  public int value() {
  return val;
  }
}

class Derived extends Base
{
  private int num = 10;

  public int lookup() {
  return num;
  }
}






class Test
{
  public static void main(String args[]) {

  Derived d = new Derived();
  System.out.println("d.value() returns " + d.value());

  }
}

输出:d.value()返回0 //我希望10是因为lookup()被覆盖,但不是0!有人可以澄清吗?

Derived的实例变量的初始化在执行其查找方法时尚未发生。如何确保在Derived调用其方法时初始化的实例变量?


问题答案:

首先,由于缺乏someLookup方法,该代码无法编译

无论如何,我相信您的问题是,由于构造函数是分层运行的,您的期望是无效的。

超类的构造函数始终在子类的构造函数之前运行,这包括子类的变量的初始化程序(实际上是作为构造函数的一部分运行)。因此,当您创建的实例时Derived,会发生以下情况:

  1. Base构造函数首先被调用。
  2. lookup()被调用,它使用中的实现Derived
  3. num返回 这是默认值,因为尚未运行Derived的构造函数和初始化程序
  4. val 设置为0。
  5. Derived初始化和构造都运行-呼吁lookup这个 点上会返回10。

通常,正是出于这个原因,从构造函数中调用非最终方法是一个坏主意,许多静态分析工具都会警告您。这类似于在构造过程中让对象引用泄漏,您可以得到一个实例,该实例使类级不变式失效(在您的情况下,Derived的num“总是”为10,但在某些情况下可以看到为0)。

编辑:请注意,对于这种 特殊 情况,无需任何其他代码,您可以通过使num常量来解决问题:

class Derived extends Base
{
  private static final int num = 10;
  ...

这实际上会做您想要的事情,因为静态初始化程序是在加载类时运行的(必须在调用构造函数之前发生)。但是,这确实假定适用于:

a)该类的所有实例共享相同的num变量;b)num无需更改(如果为true,则(a)自动为true)。

在给出的确切代码中,显然是这样,但是我希望您可能为了简洁而省略了额外的功能。

我将其包括在这里是出于比较和关注的目的,不是因为从一般意义上说,这是针对该“问题”的解决方法(因为不是这样)。



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

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

  • 问题内容: 我刚刚创建了一个类,并给了它一些变量。不幸的是,我无法在中访问这些变量。但是,相同的语法也可以在游乐场中使用… 问题答案: 类声明 的语法为: 您的include 声明本身不是 声明 ,而是 声明 -特别是带有infix运算符的 二进制表达式 。

  • 问题内容: 直观上似乎很清楚,在Java中,实例变量初始化器是按照它们在类声明中出现的顺序执行的。 在我正在使用的JDK中,似乎确实是这种情况。例如,以下内容: 打印(换句话说,y选择的默认值z)。 实际可以保证此顺序吗?我一直在浏览JLS,找不到任何明确的确认。 问题答案: 是的。 se7 JLS在12.5执行部分中介绍了实例变量的初始化顺序: … 4.执行此类的实例初始值设定项和实例变量初始值

  • 问题内容: 如何使用类型初始化变量? 因为我有错误 问题答案: 常量声明不能包含函数调用(某些例外,请参见下文),它们必须在编译时进行评估,而函数调用是在运行时进行的。 引用规格:常量: 常数值由符文,整数,浮点数,虚数或字符串文字表示,标识符表示常数,常数表达式,结果为常数的转换或某些内置结果的值函数,例如应用于任何值,或应用于某些表达式,以及应用于常量,以及应用于数字常量的复数。 并引用Spe

  • 问题内容: 以下初始化当前在调用的行中产生此错误: 无法在属性初始化程序中使用实例成员’getEventCalendar’;属性初始化程序在“自我”可用之前运行。 是否有初始化任何适当的方式与依赖于其他对象类型的值实例变量的(不只是单纯?我已经尝试过将方法从一种方法转换为一种功能,但这也无济于事。 问题答案: 您可以使用仅执行一次的闭包,该闭包捕获的属性并在执行时使用它们(=第一次使用属性)。例如