Reputation: 1782
I'm working on a Java project that uses a big class of constants like:
public final class Settings {
public static final int PORT_1 = 8888;
public static final int PORT_2 = 8889;
...
}
Now, some of the value of those constants are not available at compile time anymore so I need a way to "initialize" them at application starts (e.g. from the args[]). Once initialized there should be no way to change them. I'm not very skilled in java, how do I do this in an acceptable way?
I thought of using a singleton with something like a "one shot" set method that throws an exception if called more than one time but it seams too hacky...
Upvotes: 4
Views: 497
Reputation: 19211
Well, using system properties is a way of doing it unless there is a huge amount of constants.
private static final String CONSTANT1 = System.getProperty("my.system.property");
private static final int CONSTANT2 = Integer.valueOf(System.getProperty("my.system.property"));
System properties are passed on the command line when starting the application using the -D
flag.
If there are too many variables a static initializer can be used where a property file or similar can be read that holds the properties:
public class Constants {
private static final String CONSTANT1 = System.getProperty("my.system.property");
private static final int CONSTANT2 = Integer.valueOf(System.getProperty("my.system.property"));
private static final String CONSTANT3;
private static final String CONSTANT4;
static {
try {
final Properties props = new Properties();
props.load(
new FileInputStream(
System.getProperty("app.properties.url", "app.properties")));
CONSTANT3 = props.getProperty("my.constant.3");
CONSTANT4 = props.getProperty("my.constant.3");
} catch (IOException e) {
throw new IllegalStateException("Unable to initialize constants", e);
}
}
}
Note that if you are using some external framework such as Spring Framework or similar there is usually a built-in mechanism for this. E.g. - Spring Framework can inject properties from a property file via the @Value
annotation.
Upvotes: 2
Reputation: 10383
You can use a static initializer like this:
public final class Settings {
public static final int PORT_1;
public static final int PORT_2;
...
static {
// create the value for PORT_1:
PORT_1 = ...;
// create the value for PORT_2:
PORT_2 = ...;
}
}
The static initializer is executed during class loading. The final keywords on PORT_1
and PORT_2
protects them to be changed afterwards.
Upvotes: 3
Reputation: 328624
There is no simple way to do this in Java. One way to simulate this is to use a builder which returns an internal type (so it can write the private fields) but the internal type only has getters.
See this answer: https://stackoverflow.com/a/1953567/34088
Upvotes: 1