Sagar Pudi Sagar Pudi - 3 years ago 90
Java Question

What is the best way of reading configuration parameters from configuration file in Java?

Let us assume up to runtime we do not know what are the details of configuration(may user need to configure these parameters in

config
file before running the application.

I want to read those configuration details and need to reuse them wherever I need them in my application. For that I want to make them as global constants(
public static final
).

So, My doubt is, is there any performance implications if I read from
config
file directly from the required class? since,runtime values I can not directly put in separate
Interface
.

I am thinking it will impact performance.Please suggest me any better way to do this.

UPDATE: Can I use separate final class for configuration details?
putting all configuration details as constants in a separate
public final class


(To read all configuration details at once from the configuration file and storing them as global constants for later use in application)

Answer Source

I am thinking it will impact performance.

I doubt that this will be true.

Assuming that the application reads the configuration file just once at startup, the time taken to read the file is probably irrelevant to your application's overall performance. Indeed, the longer the application runs, the less important startup time will be.

Standard advice is to only optimize for application performance when you have concrete evidence (i.e. measurements) to say that performance is a significant issue. Then, only optimize those parts of your code that profiling tells you are really a performance bottleneck.


Can I use separate final class for configuration details

Yes it is possible to do that. Nobody is going to stop you1. However, it is a bad idea. Anything that means that you need to recompile your code to change configuration parameters is a bad idea. IMO.


To read all configuration details at once from the configuration file and storing them as global constants for later use in application.

Ah ... so want to read the values of the "constants" instead of hard-wiring them.

Yes, that is possible. And it makes more sense than hard-wiring configuration parameters into the code. But it is still not a good idea (IMO).

Why? Well lets look at what the code has to look like:

public final class Config { 
    public static final int CONST_1;
    public static final String CONST_2;

    static {
        int c1;
        String c2;
        try (Scanner s = new Scanner(new File("config.txt"))) {
            c1 = s.nextInt();
            c2 = s.next();
        } catch (IOException ex) {
            throw RuntimeException("Cannot load config properties", ex);
        }
        CONST_1 = c1;
        CONST_2 = c2; 
    }
}

First observation is that makes no difference that the class is final. It is declaring the fields as final that makes them constant. (Declaring the class as final prevents subclassing, but that has no impact on the static fields. Static fields are not affected by inheritance.)

Next observation is that this code is fragile in a number of respects:

  • If something goes wrong in the static initializer block. the unchecked exception that is thrown by the block will get wrapped as an ExceptionInInitializerError (yes ... it is an Error!!), and the Config class will be marked as erroneous.

  • If that happens, there is no realistic hope of recovering, and it possibly even a bad idea to try and diagnose the Error.

  • The code above gets executed when the Config class is initialized, but determining when that happens can be tricky.

  • If the configuration filename is a parameter, then you have the problem of getting hold of the parameter value ... before the static initialization is triggered.

Next, the code is pretty messy compared with loading the state into a instance variables. And that messiness is largely a result of having to work within the constraints of static initializers. Here's what the code looks like if you use final instance variables instead.

public final class Config { 
    public final int CONST_1;
    public final String CONST_2;

    public Config(File file) throws IOException {
        try (Scanner s = new Scanner(file)) {
            CONST_1 = s.nextInt();
            CONST_2 = s.next();
        } 
    }
}

Finally, the performance benefits of static final fields over final fields are tiny:

  • probably one or two machine instructions each time you access one of the constants,

  • possibly nothing at all if the JIT compiler is smart, and you handle the singleton Config reference appropriately.

In either case, in the vast majority of cases the benefits will be insignificant.


1 - OK ... if your code is code-reviewed, then someone will probably stop you.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download