加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 实例变量初始化中的问题

发布时间:2020-12-15 05:22:24 所属栏目:Java 来源:网络整理
导读:下面是一些示例代码, 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 =
下面是一些示例代码,

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());

  }
}

output: d.value() returns 0 // I expected 10 as lookup() is overridden,but not 0! can someone clarify this?

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

解决方法

好吧,首先,由于缺少someLookup方法,该代码无法编译.

无论如何,除此之外,我认为您的问题是由于构造函数的分层运行方式,您的预期无效.

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

>首先调用Base构造函数.
>调用lookup(),它使用Derived中的实现.
>返回> num,这是此时的默认值,因为尚未运行Derived的构造函数和初始值设定项.
> val设置为0.
> Derived初始值设定项和构造函数正在运行 – 从此时开始调用查找将返回10.

一般来说,出于这个原因从构造函数中调用非final方法是个坏主意,许多静态分析工具会警告你不要这样做.它类似于在构造期间让对象引用泄漏,你最终会得到一个使类级别不变量无效的实例(在你的情况下,Derived的num是“总是”10但在某些点它可以看作是0).

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

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

这实际上会做你想要的,因为静态初始化程序是在加载类时运行的(必须在调用构造函数之前发生).然而,这确实假设它适用于:

a)类的所有实例共享相同的num变量;
???b)num永远不需要改变(如果这是真的那么(a)自动为真).

在您给出的确切代码中显然就是这种情况,但我希望您可能会省略额外的功能以简化.

我在这里包含这个用于比较和兴趣,而不是因为它是一般意义上的这个“问题”的解决方法(因为它不是).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读