4

问题陈述

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

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

appName=MyApp
appType=TypeA

假设我appName在整个 java 项目中访问单个属性 ,

props.getProperty("appName");

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

我目前的做法

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

public static final String APP_NAME = "appName";
...
props.getProperty(APP_NAME);

但这似乎有点矫枉过正,因为它是多余的,并且仍然是一个潜在的维护问题。该键已存在于属性文件中,我将在我的实用程序类中再次声明它们。

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

4

3 回答 3

3

不,你做对了。它实际上是相当免维护的。

使用 Java Enums 会稍微好一些 - 即

public class PropertiesWrapper {
   private final Properties props;
   ...
   public String get(MyEnum key) {  return props.get(key.toString());
}

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

如果你使用枚举并删除一个枚举常量,代码仍然需要重新编译,但是当它实际上现在要求错误的东西时,它看起来并不好。此外,通过使用toString()而不是name()获取属性名称,您可以自由地toString()在枚举中覆盖以返回与常量名称不同的内容。

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

于 2013-07-18T00:19:17.740 回答
1

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

即使它存在,我也不知道它如何能够知道它key1是 aStringkey2是 a Integer。您可能仍然需要在某个地方进行投射。那,或维护一个单独的元数据文件,然后您将返回更多维护。

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

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

于 2013-07-18T00:11:53.120 回答
0

我和一位同事目前正面临一个非常相似的问题,我们做了一些研究,看看是否可以使用反射来解决这个问题。不幸的是,我们没有设法解决它,但我会尝试详细说明我们的问题和策略。也许聪明的人可以使用我们的基线来构建一些东西,以克服让我们退缩的限制。

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

这将带来两大好处:

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

我们计划在超类中定义一个使用反射来获取所有实例字段的方法。从这里开始,我们的策略是遍历所有字段,并且:

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

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

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

  1. Java 编译器可以删除有关字段名称的信息,请参阅此答案
  2. 根据 JVM,使用 Class#getDeclaredFields()可能会拒绝访问。
于 2014-04-03T10:16:23.757 回答