我有一个带有一些最终变量的活动。我将它们的值(假设它们都是字符串)提取到一个资源文件中。
问题是:
如果我在示例化时直接分配它们(如下所示): private final String PREFERENCE_NAME = getResources().getString(R.string.preference_name);
我得到以下错误: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
我理解这个问题;oncreate()方法尚未调用,这意味着我无法访问与上下文相关的方法( getResources()
).
如果我想在activity的oncreate()方法中赋值,我会得到一个错误 Cannot assign value to final variable 'PREFERENCE_NAME'
问题是:如何从资源文件中获得要分配的最终变量?如果这是不可能的,什么是解决方案的最佳实践?
提前谢谢。
5条答案
按热度按时间34gzjxbg1#
在这种情况下,我认为最好的办法就是多次调用资源。您仍然只需更改一个位置的值和对的调用
getResources()
不是很贵。yqyhoc1h2#
答案很简单,你不能。
声明的变量
final
只能在示例化对象时设置(即在构造函数中或使用初始化器代码)。任意使用
getResources().getString(R.string.preference_name);
所有时间或使用非最终变量。复杂的答案是你可以,但你不应该。
当你声明一个变量
final
编译器和虚拟机使用它来进行优化和假设。它可以做到这一点,因为变量是保证永远不变的。在初始化后更改它会导致非常奇怪的错误,所以绝对不应该这样做。以下是您的操作方法:
这将输出:
你好,世界!
你好,火星!
太好了,所以我们改变了最后一个变量。没问题吧?
好吧,换个例子:
这将输出:
你好,世界!
你好,世界!
等等,什么?
问题是编译器可以看到
message
永远都是"Hello World!"
所以它是内联的"Hello World!"
而不是我们的电话f.getMessage()
. 如果在调试器中运行此命令,您将看到调试器将示例中的更新消息反映到"Hello Mars!"
但由于变量实际上从未被访问过,因此它不会影响程序的结果。总结一下:您可以通过反射来更新final字段(假定没有安全管理器阻止您这样做),但是您不应该这样做,因为它会产生非常奇怪的副作用。
我不负责,如果你的房子得到白蚁或你的猫着火,如果你真的决定执行这个。
sh7euo9m3#
使用应用程序上下文:
创建应用程序类:
在您的清单中使用它:
在应用程序中的任意位置调用它:
pxyaymoc4#
您可以使用工厂模式来解决这个问题。
生成器是一个类,它聚合了创建对象所需的数据,完成后,您只需构建类。
在这种方法中,工厂也可以使用生成对象所需的数据,他可以轻松地创建对象,并初始化
final
调用其构造函数时的字段。你会有
smdncfj35#
您只需将其声明为final方法: