gpt4 book ai didi

构造函数中加载的 Java 属性值在构造函数之后会被恢复吗?

转载 作者:行者123 更新时间:2023-12-03 02:44:00 24 4
gpt4 key购买 nike

我注意到一些奇怪的行为。我有以下类(class):

public abstract class BaseFoo
{
public BaseFoo(String key)
{
Data data = Something.load( key );
load( data );
}

public abstract void load(Data data);
}


public class Foo extends BaseFoo
{
@Expose public long id = 0;
@Expose public String name = "";
//...

public Foo(String key)
{
super(key);
}

@Override
public void load(Data data)
{
this.id = data.id;
this.name = data.name;
//snip setting misc other fields
}
}

现在,如果我执行以下操作:

Foo f = new Foo ( "abcd" );

然后我希望 f.id 包含已加载的 Foo 记录的 id。然而,它的值实际上是0。通过调试器运行此代码,我发现在执行 public long id = 0 行之前调用 Foo.load() 。因此,尽管调用了 load() 并且确实将 id 和其他字段设置为正确的值,但这些值随后会被 public long id = 0 覆盖; 和其他变量声明..

我以前从未遇到过这个问题,通常构造函数中设置的值会覆盖变量声明中的默认值。是否是因为我通过 super 调用 load 导致这些值被覆盖?如果是这样,有方便的解决办法吗?

最佳答案

这是在构造函数中调用虚方法的问题...

执行顺序为:

  • BaseFoo 变量初始值设定项
  • BaseFoo 构造函数主体
  • Foo 变量初始值设定项
  • Foo 构造函数主体

该行为在JLS, section 12.5中有详细记录。 .

所以实际上,如果你改变这些:

@Expose public long id = 0;
@Expose public long name = "";

@Expose public long id;
@Expose public String name;

然后有条件name设置为“”(如果在到达Foo构造函数主体时它还不是非空),那我想你会没事的。

但是,我强烈建议您采用不同的设计来解决这个问题。构造函数中的虚拟方法调用很快就会变得非常困惑。

关于构造函数中加载的 Java 属性值在构造函数之后会被恢复吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19459401/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com