gpt4 book ai didi

java - 通过反射更改私有(private)最终字段

转载 作者:IT老高 更新时间:2023-10-28 20:31:11 26 4
gpt4 key购买 nike

class WithPrivateFinalField {
private final String s = "I’m totally safe";
public String toString() {
return "s = " + s;
}
}
WithPrivateFinalField pf = new WithPrivateFinalField();
System.out.println(pf);
Field f = pf.getClass().getDeclaredField("s");
f.setAccessible(true);
System.out.println("f.get(pf): " + f.get(pf));
f.set(pf, "No, you’re not!");
System.out.println(pf);
System.out.println(f.get(pf));

输出:

s = I’m totally safe
f.get(pf): I’m totally safe
s = I’m totally safe
No, you’re not!

为什么会这样,你能解释一下吗?第一个打印告诉我们私有(private)“s”字段没有改变,正如我所料。但是,如果我们通过反射获得该字段,则第二个打印显示它已更新。

最佳答案

This answer在这个主题上非常详尽。

JLS 17.5.3 最终字段的后续修改

Even then, there are a number of complications. If a final field is initialized to a compile-time constant in the field declaration, changes to the final field may not be observed, since uses of that final field are replaced at compile time with the compile-time constant.

但是,如果您仔细阅读上面的段落,您可能会找到一种解决方法(在构造函数中而不是在字段定义中设置 private final 字段):

import java.lang.reflect.Field;


public class Test {

public static void main(String[] args) throws Exception {
WithPrivateFinalField pf = new WithPrivateFinalField();
System.out.println(pf);
Field f = pf.getClass().getDeclaredField("s");
f.setAccessible(true);
System.out.println("f.get(pf): " + f.get(pf));
f.set(pf, "No, you’re not!");
System.out.println(pf);
System.out.println("f.get(pf): " + f.get(pf));
}

private class WithPrivateFinalField {
private final String s;

public WithPrivateFinalField() {
this.s = "I’m totally safe";
}
public String toString() {
return "s = " + s;
}
}

}

然后输出如下:

s = I’m totally safe
f.get(pf): I’m totally safe
s = No, you’re not!
f.get(pf): No, you’re not!

希望这会有所帮助。

关于java - 通过反射更改私有(private)最终字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4516381/

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