I have the following code:

public final class PropertyFileLoader {

    private static final Logger logger = LoggerFactory.getLogger(PropertyFileLoader.class);

    private final String propertyFileName;

    public PropertyFileLoader (String propertyFileName) {
        this.propertyFileName = propertyFileName;

    public Properties getClasspathFileAsStream () {
        final Properties properties = new Properties();
        final InputStream is = getClass().getClassLoader().getResourceAsStream(propertyFileName);

        try {
        catch (final IOException e) {
          logger.error(e.getLocalizedMessage(), e);
         //      throw new IOException();
        return properties;

How do you think, should I use static methods instead of constructor? The usage of this class:

final PropertyFileLoader loader = new PropertyFileLoader("flyway.properties");
final Properties flywayProperties = loader.getClasspathFileAsStream();

And I think add the static method such as

public static Properties getClasspathProperties(String propertyFileName){
    final PropertyFileLoader loader = new PropertyFileLoader(propertyFileName);
    return loader.getClasspathFileAsStream();`

Should I throw IOException, if I use classpath directory? If yes, why?

Could I use this class as Spring @Component with @Value? I found how to @Autoware constructor with param using @Value annotation, but how to use this at another class?

  • \$\begingroup\$ The InputStream is is never closed. \$\endgroup\$ Nov 26 '18 at 12:50

Encapsulation and information hiding

First of all, this looks poorly conceived:

public Properties getClasspathFileAsStream() {

It seems you named the method according to how it's implemented, which is a sign of bad design. Following good encapsulation / information hiding principles, users shouldn't need to know about implementation details. A method that returns Properties is better named getProperties or loadProperties. I use the former naming style when the properties are ready to return, and the latter to imply I/O operations behind the scenes (loading from filesystem, database, remote service), hinting the possibility of slowness and failures.

Initialize in constructor use static method?

This seems to be one of your main questions: should you pass the properties file name as constructor parameter, or use a static method with a filename parameter? It depends on how often you want to load the properties file.

If you need to load the properties file only once during the lifetime of the program, then there's no need to store the filename in a class field, a static method will be simple and straightforward.

If on the other hand you want to use getProperties multiple times, then it makes sense to store data in class fields. Even so, you have two alternatives:

  • Store the filename in a field, and use a loadProperties method to load the content of the file on every call.

  • Load the content of the file in the constructor, and store the Properties data in a field, returned by getProperties. In this alternative there's no need to store the filename in a field at all.

Again, the suitable alternative depends on how you want to use this class, and if the content of the properties file is expected to change during the execution of the program.

Throw an exception or not

Throw an exception if the caller can or should handle it. Perhaps the caller should try to load properties from a different source. Or perhaps it should exit the program in case the properties cannot be loaded.

Don't throw an exception if properties are not essential data, and missing data is not a problem. In this case you can handle I/O exceptions in this class, and return new Properties().

The right approach depends on your use case.


There isn't any useful state in the PropertyFileLoader, nor will there be any subclass of PropertyFileLoader that will have state. I think that all you need is a static method (basically your second version, but not swallowing the exception):

public class PropertyFileLoader {
    public static Properties load(String filename) throws IOException {

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.