首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java:使用属性文件中的键名而不使用硬编码字符串作为键

Java:使用属性文件中的键名而不使用硬编码字符串作为键
EN

Stack Overflow用户
提问于 2013-07-18 00:09:32
回答 3查看 5.9K关注 0票数 4

问题陈述

我有一个在整个java项目中访问的属性文件。

我的.properties文件的示例内容:

代码语言:javascript
复制
appName=MyApp
appType=TypeA

假设我访问了整个java项目中的单个属性appName

代码语言:javascript
复制
props.getProperty("appName");

我不想通过迭代属性文件来获得属性值;我只是从属性文件中获得一个属性值。但我不喜欢必须使用硬编码字符串来访问属性的事实,因为这可能导致维护问题(即更改硬编码字符串的所有实例)。

我现在的方法

在我的当前方法中,我有一个实用工具类,它创建表示属性文件中的键名的静态最终变量,然后使用该变量访问属性值:

代码语言:javascript
复制
public static final String APP_NAME = "appName";
...
props.getProperty(APP_NAME);

但是这看起来有点过分,因为它是多余的,并且仍然是一个潜在的维护问题。这个键已经存在于属性文件中,我将在我的实用工具类中再次声明它们。

在使用get方法访问属性值时,是否有一种更“免维护”的方法来访问代码中的密钥名?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-18 00:19:17

不,你做得对。而且它实际上是相当免费的。

使用Java Enum会稍微好一些--例如

代码语言:javascript
复制
public class PropertiesWrapper {
   private final Properties props;
   ...
   public String get(MyEnum key) {  return props.get(key.toString());
}

原因是,即使您使该字符串成为常量,如果不重新编译使用该常量的所有代码,则永远无法更改该字符串--因为编译器将在编译时用"appName“替换该常量。

如果您使用枚举并删除枚举常量,那么代码仍然需要重新编译,但是当它现在要求错误的时候,它看起来就不太好了。此外,通过使用toString()而不是name()来获取属性名,您可以在枚举中重写toString(),以返回与常量名称不同的内容。

使用枚举的缺点是,如果没有其他方式访问Properties,系统就无法查找编译时所不知道的任何内容。

票数 3
EN

Stack Overflow用户

发布于 2013-07-18 00:11:53

可能存在一个库,它将读取属性文件并将其生成为包含getter的源文件。然后,您必须用代码编译该源文件。那将是一个非常漂亮的图书馆。但是,如果这不存在的话,我不认为有其他方法可以做到这一点。

即使它存在,我也看不出它如何能够知道key1Stringkey2Integer。你可能还得找个地方投。这样,或者维护一个单独的元数据文件,您就可以重新进行更多的维护。

问题是,您可以随时更改属性文件键,而编译器无法知道您做了什么。

我能给您的最好的是用于读取配置文件的库。看看Apache配置库

票数 1
EN

Stack Overflow用户

发布于 2014-04-03 10:16:23

我和一位同事目前正面临一个非常类似的问题,我们做了一些研究,看看是否可以通过反思来解决这个问题。不幸的是,我们没有设法解决这一问题,但我将设法详细阐述我们的问题和策略。也许某个聪明的人可以利用我们的基线来构建一些东西,来克服阻碍我们前进的局限。

问题陈述:我们希望读取属性文件中的值,并将这些值分配给Java (一个设置对象)中的字段。键名对我们来说并不重要,因此,简单地使用Java字段的名称作为键名是最优的。

这将带来两大好处:

  1. 首先,它将允许我们删除许多冗余的字符串常量。
  2. 其次,它允许我们在一个地方定义字段分配,因为我们的设置类是使用继承实现的。

我们计划在超类中定义一个使用反射获取所有实例字段的方法。从现在起,我们的策略将是遍历所有领域,并:

  1. 找出这个字段的名字,
  2. 使用此名称在属性文件中查找属性,
  3. 获取字段的类型,并使用此类型转换从属性文件读取的字符串值,然后将其分配给当前字段。

使用这种方法,只需添加一个新的实例字段,就可以添加一个新属性。不需要用于读取或写入新属性的额外代码。

不幸的是,由于以下两个问题,这是不可行的:

  1. Java编译器可以删除有关字段名的信息,请参阅这个答案
  2. 根据JVM的不同,使用Class#getDeclaredFields()可能会拒绝访问。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17712403

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档