问题陈述
我有一个在我的java项目中访问的属性文件。
我的.properties
文件的示例内容:
appName=MyApp
appType=TypeA
假设我在整个java项目中访问单个属性appName
props.getProperty("appName");
我不想遍历属性文件来获取属性值;我只是从属性文件中获取单个属性值。但我不喜欢我必须使用硬编码字符串访问该属性的事实,因为它可能导致维护问题(即更改硬编码字符串的所有实例)。
我目前的做法
在我目前的方法中,我有一个实用程序类,它创建表示属性文件中的键名的静态最终变量,然后我使用该变量来访问属性值:
public static final String APP_NAME = "appName";
...
props.getProperty(APP_NAME);
但这看起来有点过分,因为它是多余的,并且仍然是潜在的维护问题。密钥已存在于属性文件中,我在我的实用程序类中再次声明它们。
使用get方法访问属性值时,是否有更“免维护”的方式访问代码中的键名?
答案 0 :(得分:3)
不,你做得对。它实际上相当免维护。
使用Java Enums会稍微好一点 - 即
public class PropertiesWrapper {
private final Properties props;
...
public String get(MyEnum key) { return props.get(key.toString());
}
原因是,即使你将String变为常量,也不能在不重新编译使用常量的所有代码的情况下更改它 - 因为编译器会在编译时用“appName”替换常量。
如果你使用枚举并删除枚举常量,代码仍然需要重新编译,但是当它实际上现在要求错误时它似乎不会很好。此外,通过使用toString()
代替name()
来获取属性名称,您可以在枚举中覆盖toString()
以返回与常量名称不同的内容。
使用枚举的缺点是系统无法在没有其他方法访问Properties
的情况下查找编译时未知的任何内容。
答案 1 :(得分:1)
可能有一个库会读取属性文件并将其生成到带有getter的源文件中。然后,您必须使用您的代码编译该源文件。那将是一个非常漂亮的图书馆。但是,如果这不存在,我认为没有其他办法可以做到这一点。
即使它存在,我也看不出它如何能够知道key1
是String
且key2
是Integer
。你可能仍然需要在某处施放。那,或者维护一个单独的元数据文件,然后你又回到了更多的维护。
问题是,您可以随时更改属性文件密钥,编译器无法知道您是否已执行此操作。
我能给你的最好的是用于阅读配置文件的库。查看Apache Configuration library。
答案 2 :(得分:0)
一位同事和我目前正面临着一个非常相似的问题,我们做了一些研究,看看是否可以通过反思解决这个问题。不幸的是,我们没有设法解决它,但我会尝试详细说明我们的问题和策略。也许聪明的人可以使用我们的基线来构建一些克服了让我们回归的局限的东西。
问题陈述:我们想要读取属性文件中的值,并将这些值分配给Java对象(设置对象)中的字段。键名对我们来说无关紧要,因此最好只使用Java字段的名称作为键名。
这将带来两大好处:
我们计划在超类中定义一个方法,该方法将使用反射来获取所有实例字段。从这里开始,我们的策略是遍历所有领域并且:
使用这种方法,只需添加一个新的实例字段即可添加新属性。不需要额外的代码来阅读或写新属性。
不幸的是,由于两个问题,这是不可行的:
Class#getDeclaredFields()
可能会拒绝访问。