Java:使用属性文件中的键名,而不使用硬编码字符串作为键
问题陈述 我有一个在整个java项目中都可以访问的属性文件 myJava:使用属性文件中的键名,而不使用硬编码字符串作为键,java,properties,configuration,hard-coding,Java,Properties,Configuration,Hard Coding,问题陈述 我有一个在整个java项目中都可以访问的属性文件 my.properties文件的内容示例: appName=MyApp appType=TypeA 假设我在整个java项目中访问单个属性,appName props.getProperty("appName"); 我不想通过迭代属性文件来获取属性值;我只是从属性文件中获取一个属性值。但我不喜欢必须使用硬编码字符串访问属性,因为这可能会导致维护问题(即更改硬编码字符串的所有实例) 我目前的做法 在我当前的方法中,我有一个实用程序类,
.properties
文件的内容示例:
appName=MyApp
appType=TypeA
假设我在整个java项目中访问单个属性,appName
props.getProperty("appName");
我不想通过迭代属性文件来获取属性值;我只是从属性文件中获取一个属性值。但我不喜欢必须使用硬编码字符串访问属性,因为这可能会导致维护问题(即更改硬编码字符串的所有实例)
我目前的做法
在我当前的方法中,我有一个实用程序类,它创建表示属性文件中键名称的静态最终变量,然后使用该变量访问属性值:
public static final String APP_NAME = "appName";
...
props.getProperty(APP_NAME);
但这似乎有些过分,因为它是多余的,而且仍然是一个潜在的维护问题。该密钥已经存在于属性文件中,我将在实用程序类中再次声明它们
在使用get方法访问属性值时,是否有一种更“免维护”的方式来访问代码中的键名?可能有一个库,它将读取属性文件并将其生成到带有getter的源文件中。然后,您必须用代码编译该源文件。那将是一个相当漂亮的图书馆。但是,如果这不存在,我认为没有其他方法可以做到这一点 即使它存在,我也不知道它怎么能知道
key1
是String
,而key2
是整数。你可能还得找个地方。或者维护一个单独的元数据文件,然后再进行更多的维护
问题是,您可以随时更改属性文件键,而编译器无法知道您是否这样做了
我能给你的最好的是用于读取配置文件的库。查看。不,你做得对。而且它实际上相当免维护
使用Java枚举会稍微好一点,即
public class PropertiesWrapper {
private final Properties props;
...
public String get(MyEnum key) { return props.get(key.toString());
}
原因是,即使您将该字符串设置为常量,也无法在不重新编译所有使用该常量的代码的情况下更改它,因为编译器将在编译时用“appName”替换该常量
如果使用enum并删除enum常量,代码仍然需要重新编译,但当它现在实际请求错误的东西时,它看起来不会很好。另外,通过使用toString()
而不是name()
来获取属性名,您可以在枚举中自由重写toString()
,以返回与常量名不同的内容
使用enum的缺点是,如果没有访问属性的替代方法,系统无法查找编译时未知的任何内容。我和一位同事目前面临着一个非常类似的问题,我们做了一些研究,看看是否可以使用反射来解决这个问题。不幸的是,我们没有设法解决这个问题,但我将试图详细阐述我们的问题和策略。也许聪明的人可以利用我们的基线来构建一些东西,以克服让我们落后的限制
问题陈述:我们希望读取属性文件中的值,并将这些值分配给Java对象(设置对象)中的字段。键名对我们来说并不重要,因此最好只使用Java字段的名称作为键名
这将带来两大好处:
首先,它允许我们删除大量冗余的字符串常量
其次,它允许我们在一个地方定义字段分配,因为我们的设置类是使用继承实现的
我们计划在超类中定义一个方法,该方法将使用反射来获取所有实例字段。从这里开始,我们的战略将是在所有领域进行循环,并:
获取字段中的名称
使用此名称在属性文件中查找属性
获取字段的类型,并使用此类型转换从属性文件读取的字符串值,然后将其分配给当前字段
使用这种方法,只需添加一个新的实例字段,就可以添加一个新属性。不需要额外的代码来读取或写入新属性
不幸的是,由于两个问题,这是不可行的:
Java编译器可以删除有关字段名的信息,请参阅
根据JVM的不同,使用可能会拒绝访问
我会说,通常不会。在某个时候,你需要直接或间接地知道关键是什么……嗯,我恐怕是这样。我只是想知道是否有一种聪明的方法可以直接访问密钥名的.properties文件@感谢您的回复,我认为您当前的方法是普遍接受的方法,因为您只需要在一个地方修改代码。你可以在一个变量和一个键之间生成一个映射,但是你又回到了原来的位置……就像MadProgrammer说的那样,在某个时候你必须定义键。要从文件中读取密钥,您必须依赖拥有所有密钥的properites文件,并限制您动态构造属性文件的能力。是的,我知道编译器不会知道属性文件密钥的更改。我想这个问题更多的是在开发过程中:例如,当您意识到您想要更改属性文件密钥的名称,而不必担心维护问题时,等等。尽管不是为了这个目的,NetBeans annotation确实做到了这一点。