Of course! A "Java Properties util" typically refers to a set of utility methods for working with the .properties files, which are a common way to manage configuration in Java applications.
While the standard java.util.Properties class is powerful, it can be a bit verbose and lacks some modern conveniences. A good utility class can simplify common tasks like reading, writing, and strongly-typed property access.
Here is a comprehensive guide, starting with the basics and building up to a robust, reusable PropertiesUtil class.
The Basics: Using java.util.Properties
Before creating a utility, it's essential to understand the standard library.
Reading a Properties File
You load properties from a file (e.g., config.properties) using an InputStream.
config.properties
# Database Configuration db.url=jdbc:mysql://localhost:3306/mydb db.user=admin db.password=secret app.name=My Awesome App app.version=1.2.3 feature.enabled=true
Java Code to Load

import java.io.InputStream;
import java.util.Properties;
public class BasicPropertiesExample {
public static void main(String[] args) {
Properties props = new Properties();
// Use try-with-resources to automatically close the InputStream
try (InputStream input = BasicPropertiesExample.class.getClassLoader()
.getResourceAsStream("config.properties")) {
if (input == null) {
System.out.println("Sorry, unable to find config.properties");
return;
}
// Load the properties file
props.load(input);
// Get individual properties
String dbUrl = props.getProperty("db.url");
String appVersion = props.getProperty("app.version");
System.out.println("Database URL: " + dbUrl);
System.out.println("App Version: " + appVersion);
// Get a property with a default value if it's not found
String defaultHost = "localhost";
String host = props.getProperty("server.host", defaultHost);
System.out.println("Server Host: " + host); // Will print "localhost"
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Writing a Properties File
You can also save properties to a file using an OutputStream.
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Properties;
public class WritePropertiesExample {
public static void main(String[] args) {
Properties props = new Properties();
props.setProperty("last.login.user", "john.doe");
props.setProperty("ui.theme", "dark");
try (OutputStream output = new FileOutputStream("config-out.properties")) {
// Save properties to the file
// The 'true' argument in store() enables comments and timestamp
props.store(output, "Application Configuration File");
System.out.println("Properties file saved successfully!");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Creating a PropertiesUtil for Common Tasks
Now, let's create a utility class to encapsulate these common operations. This will make your code cleaner and more reusable.

PropertiesUtil.java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Properties;
/**
* A utility class for simplifying interactions with .properties files.
*/
public final class PropertiesUtil {
// Private constructor to prevent instantiation
private PropertiesUtil() {
throw new UnsupportedOperationException("Utility class cannot be instantiated.");
}
/**
* Loads properties from a file on the classpath.
*
* @param fileName The name of the properties file (e.g., "config.properties").
* @return A Properties object loaded with the file's content.
* @throws IOException if the file cannot be found or read.
* @throws IllegalArgumentException if the file is not found on the classpath.
*/
public static Properties loadFromResource(String fileName) throws IOException {
Properties props = new Properties();
try (InputStream input = PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName)) {
if (input == null) {
throw new IllegalArgumentException("Sorry, unable to find " + fileName + " on the classpath.");
}
props.load(input);
return props;
}
}
/**
* Loads properties from a file system path.
*
* @param filePath The absolute or relative path to the properties file.
* @return A Properties object loaded with the file's content.
* @throws IOException if the file cannot be found or read.
*/
public static Properties loadFromFile(String filePath) throws IOException {
Properties props = new Properties();
try (InputStream input = new java.io.FileInputStream(filePath)) {
props.load(input);
return props;
}
}
/**
* Saves properties to a file.
*
* @param props The Properties object to save.
* @param filePath The path where the file will be saved.
* @param comments A comment to be written at the top of the file. Can be null.
* @throws IOException if an error occurs during writing.
*/
public static void saveToFile(Properties props, String filePath, String comments) throws IOException {
try (OutputStream output = new java.io.FileOutputStream(filePath)) {
props.store(output, comments);
}
}
}
How to use the PropertiesUtil:
public class PropertiesUtilExample {
public static void main(String[] args) {
try {
// 1. Load from classpath (common for internal config files)
Properties config = PropertiesUtil.loadFromResource("config.properties");
System.out.println("Loaded from classpath: " + config.getProperty("app.name"));
// 2. Load from a file path (useful for user-specific or external config)
// String userHome = System.getProperty("user.home");
// Properties userConfig = PropertiesUtil.loadFromFile(userHome + "/.myapp/config.properties");
// System.out.println("Loaded from file: " + userConfig.getProperty("some.setting"));
// 3. Modify and save properties
config.setProperty("app.last.accessed", java.time.LocalDateTime.now().toString());
PropertiesUtil.saveToFile(config, "config-updated.properties", "Updated Configuration");
System.out.println("Properties saved to config-updated.properties");
} catch (IOException e) {
System.err.println("An error occurred while handling properties: " + e.getMessage());
e.printStackTrace();
}
}
}
Advanced PropertiesUtil: Strongly-Typed Getters
A common pain point is that Properties.get() always returns a String. You often need to convert to int, boolean, long, etc. Let's extend our utility with strongly-typed methods.
Here is the enhanced PropertiesUtil.java:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
public final class PropertiesUtil {
private PropertiesUtil() {}
// --- Loading Methods (from before) ---
public static Properties loadFromResource(String fileName) throws IOException {
Properties props = new Properties();
try (InputStream input = PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName)) {
if (input == null) throw new IllegalArgumentException("File not found: " + fileName);
props.load(input);
return props;
}
}
public static Properties loadFromFile(String filePath) throws IOException {
Properties props = new Properties();
try (InputStream input = new java.io.FileInputStream(filePath)) {
props.load(input);
return props;
}
}
// --- Saving Methods (from before) ---
public static void saveToFile(Properties props, String filePath, String comments) throws IOException {
try (OutputStream output = new java.io.FileOutputStream(filePath)) {
props.store(output, comments);
}
}
// --- Strongly-Typed Getter Methods ---
/**
* Gets a String property.
*/
public static String getString(Properties props, String key, String defaultValue) {
return props.getProperty(key, defaultValue);
}
/**
* Gets a String property with no default value (returns null if not found).
*/
public static String getString(Properties props, String key) {
return props.getProperty(key);
}
/**
* Gets an integer property.
*
* @throws NumberFormatException if the value is not a valid integer.
*/
public static int getInt(Properties props, String key, int defaultValue) {
String value = props.getProperty(key);
if (value == null) {
return defaultValue;
}
return Integer.parseInt(value);
}
/**
* Gets a boolean property.
* Accepts "true"/"false", "yes"/"no", "on"/"off" (case-insensitive).
*/
public static boolean getBoolean(Properties props, String key, boolean defaultValue) {
String value = props.getProperty(key);
if (value == null) {
return defaultValue;
}
// Boolean.parseBoolean is too strict, this is more flexible
return value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("on");
}
/**
* Gets a long property.
*
* @throws NumberFormatException if the value is not a valid long.
*/
public static long getLong(Properties props, String key, long defaultValue) {
String value = props.getProperty(key);
if (value == null) {
return defaultValue;
}
return Long.parseLong(value);
}
}

