java - 在构造函数中使用反射设置最终字段
java - Set final fields with reflection in Constructor
我正在尝试制作一个多语言应用程序,其中包含多个 *.properties
文件中的消息。我已经开始做这样的事情了:
public Language(@NotNull Map<String, String> info) {
Validate.notNull(info, "Language information cannot be null");
this.PLUGIN_PREFIX = info.get("PLUGIN_PREFIX");
this.ARGUMENT_CODE = info.get("ARGUMENT_CODE");
// etc...
}
现在,有很多消息,我不想每次都输入相同的内容(加上我可能会出现错别字,这可能是个问题...)。
我第一个想到的解决方案是循环遍历所有类似的字段(大写,最终,非静态等),然后使用反射将字段名称作为键来设置它作为价值。显然编译器不会让我,因为它认为 final 字段还没有被初始化。
像这样:
public Language(@NotNull Map<String, String> info) {
Validate.notNull(info, "Language information cannot be null");
Field[] fields = /* TODO get fields */ new Field[0];
for (Field f : fields) f.set(f.getName(), info.get(f.getName()));
}
有什么办法可以做到吗?或者有更好的解决方案吗?
编辑:快速命名约定问题,这些最终的“常量”应该大写吗?
通常,您不会将文本消息直接存储在常量中,而是只存储消息键。然后您使用这些键来获取地图中的实际文本消息。
可以直接使用地图,但是在Java中有ResourceBundle。可以直接从 .properties 文件加载 ResourceBundle。
我的-bundle_en.properties:
my.message=Hello, world!
my-bundle_fr.properties:
my.message=Bonjour tout le monde!
my-bundle_de.properties:
my.message=Hallo Welt!
Something.java:
public static final MY_MESSAGE = "my.message";
ResourceBundle bundle = ResourceBundle.getBundle("my-bundle");
String text = bundle.getMessage(MY_MESSAGE);
System.out.println(text);
我正在尝试制作一个多语言应用程序,其中包含多个 *.properties
文件中的消息。我已经开始做这样的事情了:
public Language(@NotNull Map<String, String> info) {
Validate.notNull(info, "Language information cannot be null");
this.PLUGIN_PREFIX = info.get("PLUGIN_PREFIX");
this.ARGUMENT_CODE = info.get("ARGUMENT_CODE");
// etc...
}
现在,有很多消息,我不想每次都输入相同的内容(加上我可能会出现错别字,这可能是个问题...)。
我第一个想到的解决方案是循环遍历所有类似的字段(大写,最终,非静态等),然后使用反射将字段名称作为键来设置它作为价值。显然编译器不会让我,因为它认为 final 字段还没有被初始化。
像这样:
public Language(@NotNull Map<String, String> info) {
Validate.notNull(info, "Language information cannot be null");
Field[] fields = /* TODO get fields */ new Field[0];
for (Field f : fields) f.set(f.getName(), info.get(f.getName()));
}
有什么办法可以做到吗?或者有更好的解决方案吗?
编辑:快速命名约定问题,这些最终的“常量”应该大写吗?
通常,您不会将文本消息直接存储在常量中,而是只存储消息键。然后您使用这些键来获取地图中的实际文本消息。
可以直接使用地图,但是在Java中有ResourceBundle。可以直接从 .properties 文件加载 ResourceBundle。
我的-bundle_en.properties:
my.message=Hello, world!
my-bundle_fr.properties:
my.message=Bonjour tout le monde!
my-bundle_de.properties:
my.message=Hallo Welt!
Something.java:
public static final MY_MESSAGE = "my.message";
ResourceBundle bundle = ResourceBundle.getBundle("my-bundle");
String text = bundle.getMessage(MY_MESSAGE);
System.out.println(text);