Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:使用属性文件中的键名,而不使用硬编码字符串作为键_Java_Properties_Configuration_Hard Coding - Fatal编程技术网

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

Java:使用属性文件中的键名,而不使用硬编码字符串作为键,java,properties,configuration,hard-coding,Java,Properties,Configuration,Hard Coding,问题陈述 我有一个在整个java项目中都可以访问的属性文件 my.properties文件的内容示例: appName=MyApp appType=TypeA 假设我在整个java项目中访问单个属性,appName props.getProperty("appName"); 我不想通过迭代属性文件来获取属性值;我只是从属性文件中获取一个属性值。但我不喜欢必须使用硬编码字符串访问属性,因为这可能会导致维护问题(即更改硬编码字符串的所有实例) 我目前的做法 在我当前的方法中,我有一个实用程序类,

问题陈述

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

my
.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确实做到了这一点。