1 回答
TA贡献1843条经验 获得超7个赞
当你声明一个类时
public class Server {
private int pingFrequency = 500;
public Server() {
}
}
它与
public class Server {
private int pingFrequency;
public Server() {
pingFrequency = 500;
}
}
要么
public class Server {
private int pingFrequency;
{
pingFrequency = 500;
}
public Server() {
}
}
事实上,所有三个变体都被编译为相同的字节码。所有字段初始值设定项和实例初始值设定项块的代码都被复制到此类的每个构造函数¹中,就在超级构造函数调用和构造函数的其余部分之间。[ JLS §12.5 ]
¹ 不委托给此类的另一个构造函数
改变赋值的唯一方法是修改所有构造函数的代码,改变赋值。这不能通过反射来完成,而只能通过字节码操作工具来完成。
请注意,当该字段已被声明时final,例如
public class Server {
private final int pingFrequency = 500;
public Server() {
}
}
会有在字节码的属性,报告恒定值[ JVMS§4.7.2 ],另外的指配。但是,对于这样的编译时常量,每个普通的读取访问都将在编译时替换为常量值[ JLS §13.1 ],因此即使更改分配也不会有任何影响(也不会更改属性)[ JLS §13.4.9 ]。试图替换该字段的实际用途会引起您无法将它们与常量 number 的其他用途区分开来的问题500。
如果字段是staticand final,则根本没有赋值,则常量值属性将用于初始化字段,但是,更改它与常量实例字段的影响一样小,因为字段访问仍被替换为旧的常数值。
添加回答
举报