简单的答案是你不能。
声明为final 的变量只能在对象被实例化时设置(即在构造函数中或使用初始化代码)。
要么一直使用getResources().getString(R.string.preference_name);,要么使用非最终变量。
复杂的答案是你可以但你不应该。
当您声明变量 final 时,编译器和 VM 使用它来进行优化和假设。它可以这样做,因为保证变量永远不会改变。在初始化后更改它可能会导致非常奇怪的错误,因此您绝对不应该这样做。
你是这样做的:
public class FinalMessage {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
FinalMessage f = new FinalMessage("Hello World!");
System.out.println(f.getMessage());
f.changeFinalMessage("Hello Mars!");
System.out.println(f.getMessage());
}
private final String message;
public FinalMessage(String message) {
this.message = message;
}
void changeFinalMessage(String newMessage) throws IllegalAccessException, NoSuchFieldException {
final Field field = FinalMessage.class.getDeclaredField("message");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(this, newMessage);
}
String getMessage() {
return message;
}
}
这将输出:
世界你好!
你好火星!
太好了,所以我们更改了最终变量。没问题吧?
好吧,以这个例子代替:
public class FinalMessage {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
FinalMessage f = new FinalMessage();
System.out.println(f.getMessage());
f.changeFinalMessage("Hello Mars!");
System.out.println(f.getMessage());
}
private final String message = "Hello World!";
void changeFinalMessage(String newMessage) throws IllegalAccessException, NoSuchFieldException {
final Field field = FinalMessage.class.getDeclaredField("message");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(this, newMessage);
}
String getMessage() {
return message;
}
}
这将输出:
世界你好!
世界你好!
等等,什么?
问题是编译器可以看到变量message 总是"Hello World!",所以它内联"Hello World!" 而不是我们对f.getMessage() 的调用。如果您在调试器中运行它,您将看到调试器将实例中的更新消息反映到"Hello Mars!",但由于该变量实际上从未被访问过,因此不会影响程序的结果。
总结一下:您可以通过反射更新 final 字段(假设不存在阻止您这样做的Security Manager),但您不应该这样做,因为它可能会产生非常非常奇怪的副作用。
如果您真的决定实施,如果您的房子有白蚁或您的猫着火,我概不负责。