[英]Java property values loaded in constructor are being reverted after the constructor?
I'm noticing some strange behavior. 我注意到一些奇怪的行为。 I have the following classes:
我有以下课程:
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
}
}
Now, if I do the following: 现在,如果我执行以下操作:
Foo f = new Foo ( "abcd" );
Then I expect f.id
to contain the id of the Foo
record which was loaded. 然后我希望
f.id
包含加载的Foo
记录的id。 However, its value is actually 0
. 但是,它的值实际上是
0
。 By running this code through a debugger, I've found that Foo.load()
is called before the public long id = 0
line is executed. 通过调试器运行此代码,我发现在执行
public long id = 0
行之前调用了Foo.load()
。 So, although load()
is called and it does set id
and other fields to their correct values, those values are then overwritten by the public long id = 0;
因此,尽管调用了
load()
并且确实将id
和其他字段设置为其正确的值,但是这些值随后被public long id = 0;
覆盖public long id = 0;
and other variable declarations.. 和其他变量声明..
I've never come across this issue before, usually the values set in a constructor overwrite the default values in the variable declaration. 我以前从未遇到过此问题,通常在构造函数中设置的值会覆盖变量声明中的默认值。 Is it because I'm calling load through
super
that the values are being overwritten? 是因为我通过
super
调用负载值是否被覆盖? If so, is there a convenient fix for this? 如果是这样,是否有一个方便的解决方法?
This is the problem with calling virtual methods in a constructor... 这是在构造函数中调用虚方法的问题...
The order of execution is: 执行顺序为:
That behaviour is well documented in the JLS, section 12.5 . 这种行为在JLS第12.5节中有详细记载。
So actually , if you change these: 实际上 ,如果你改变这些:
@Expose public long id = 0;
@Expose public long name = "";
to 至
@Expose public long id;
@Expose public String name;
and then conditionally set name
to "" if it's not already non-null by the time you get to the Foo
constructor body, then I think you'll be okay. 然后有条件地将
name
设置为“”,如果到Foo
构造函数主体时name
还不是非null的话,那么我认为您会没事的。
However, I'd strongly advise you to approach this with a different design. 但是,我强烈建议您采用其他设计方法。 Virtual method calls in constructors get really messy really quickly.
构造函数中的虚方法调用非常快速地变得非常混乱。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.