Java: using key names from a properties file without using hardcoded strings as keys

Description of the problem

I have a properties file that is accessed throughout the entire java project.

An example of the contents of my .properties file:

 appName=MyApp appType=TypeA 

Let's say I access the only property appName , all throughout the java project

 props.getProperty("appName"); 

I do not want to iterate over the properties file to get the property value; I just get one property value from the properties file. But I don’t like the fact that I need to access the property using a hard-coded string, because this can lead to maintenance problems (i.e. Change all instances of the hard-coded string).

My current approach

In my current approach, I have a utility class that creates static final variables that represent the key names in a property file, and then I use this variable to access the property value:

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

But this seems redundant because it is redundant and is still a potential service concern. The key already exists in the properties file, and I declare them again in my utility class.

Is there a more “maintenance free” way to access the key name in my code when using get methods to access property values?

+4
source share
3 answers

No, you are doing everything right. And it actually does not require maintenance.

Using Java Enums will be a little preferable - for example,

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

The reason is that even if you make this String constant, you can never change it without recompiling all the code that uses the constant, because the compiler will replace the constant with "appName" at compile time.

If you use enumerations and remove the enumeration constant, the code still needs to be recompiled, but it doesn't seem to be good when it really asks for the wrong thing. Also, by using toString() instead of name() to get the name of the property, you can override toString() in your enum to return something other than the name of the constant.

The downside of using enumerations is that the system cannot search for something that was not known at compile time without any alternative way to access Properties .

+3
source

There may be a library that will read the properties file and generate it into the source file using getters. Then you will have to compile this source file with code. It would be a pretty pretty library. But, if this does not exist, I do not think that there is another way to do this.

Even if it exists, I don’t see how it could know that key1 is String and key2 is Integer . You still have to throw it somewhere. This is either to save a separate metadata file, and then you will return to more maintenance.

The problem is that you can change the keys of the properties file at any time, and the compiler does not know that you did this.

The best I can give you are libraries designed to read configuration files. Check out the Apache Configuration library .

+1
source

My colleague and I are faced with a very similar question at the moment, and we did some research to understand whether this can be solved with the help of reflection. Unfortunately, we were not able to solve this, but I will try to elaborate on our problem and strategy. Perhaps someone smart can use our baseline to create something that will overcome the limitations that have thrown us back.

Problem: We want to read the values ​​in the properties file and assign these values ​​to the fields in the Java object (settings object). Key names are not important to us, and therefore it would be optimal to just use Java field names as key names.

This will bring two big benefits:

  • First, it will allow us to remove many redundant string constants.
  • Secondly, this will allow us to determine the purpose of the fields in one place, since our configuration classes are implemented using inheritance.

We planned to define a method in a superclass that would use reflection to get all the fields of an instance. Forward from here, our strategy would be to cross all the fields and:

  • enter the field name,
  • use this name to search for a property in a property file,
  • get the type of the field and use this type to convert the value of the string read from the properties file, and then assign it to the current field.

Using this approach, one could add a new property by simply adding a new instance field. No additional code is required to read and write the new property.

Unfortunately, this is not possible for two reasons:

0
source

Source: https://habr.com/ru/post/1491987/


All Articles