final static
字段的值在引用方法时是否会发生变化?例如,如果您运行以下代码:
private static final String example = Example.getExampleString();
当方法example
返回不同的内容时,getExampleString()
的值是否会发生变化?
答案 0 :(得分:3)
您问题中的代码是初始值设定项。因此,Example.getExampleString()
在变量首次在内存中定义时被称为一次,之后,example
将包含函数返回的值,一次被调用
因此,如果您运行程序两次,变量可能会为每次运行设置不同的值,但是一旦设置了变量,就无法在程序运行时更改它。
举个例子,试试这个:
import java.util.Random;
public class VarTest {
private static final Random rng = new Random();
private static final String example = Integer.toString(rng.nextInt());
public static void main(String[] args) {
System.out.println(example);
System.out.println(rng.nextInt());
System.out.println(rng.nextInt());
System.out.println(example);
}
}
如果您运行此程序,您会看到nextInt
每次调用都会返回不同的值,但example
在程序中保持不变。如果再次运行它,example
可能与上次运行时不同,但example
在运行时仍未更改。 (由于example
的工作原理,您可能需要在两次运行之间等待几秒钟或几分钟才能看到Random
的不同值。)
答案 1 :(得分:1)
不,它不能。 example
为final
,并在初始化类时初始化为getExampleString()
返回的参考值。由于它是final
,因此无法使用其他参考值重新分配变量。
您可以通过反射来完成,但这与您在初始化表达式中调用的方法无关。
答案 2 :(得分:0)
忘记变量最终为静态的部分,方法本身只调用一次以提供String。
答案 3 :(得分:0)
既然您询问是否可以,那么答案是 ,不幸的是是 。
但是你需要记住final
字段的目的是让程序员只设置一次它的值,所以你永远不应该试图改变它。
以下是您如何做到这一点的示例,但这仅用于(不良)教育目的。
由于Example.getExampleString()
的结果不能被视为编译时常量表达式,因此example
不被视为常量变量,因此其值不会在使用example
的代码中内联。所以基于this answer,您可以执行类似
class Example {
private static final String example = Example.getExampleString();
private static String getExampleString() {
return "foo";
}
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
public static void main(String[] args) throws Exception {
System.out.println(Example.example);
setFinalStatic(Example.class.getDeclaredField("example"), "bar");
System.out.println(Example.example);
}
}
将返回
foo
bar
因此,在这种情况下,您可以更改example
字段的值。