«1. Обзор

Большинству Java-приложений в какой-то момент необходимо использовать свойства, как правило, для хранения простых параметров в виде пар ключ-значение вне скомпилированного кода.

Итак, язык имеет первоклассную поддержку свойств — java.util.Properties — служебный класс, предназначенный для обработки файлов конфигурации такого типа.

Это то, на чем мы сосредоточимся в этой статье.

2. Загрузка свойств

2.1. Из файлов свойств

Давайте начнем с примера загрузки пар ключ-значение из файлов свойств; мы загружаем два файла, которые доступны в нашем пути к классам:

app.properties:

version=1.0
name=TestApp
date=2016-11-12

И catalog:

c1=files
c2=images
c3=videos

Обратите внимание, что хотя в файлах свойств рекомендуется использовать «.properties». €œ суффикс не нужен.

Теперь мы можем очень просто загрузить их в экземпляр Properties:

String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
String appConfigPath = rootPath + "app.properties";
String catalogConfigPath = rootPath + "catalog";

Properties appProps = new Properties();
appProps.load(new FileInputStream(appConfigPath));

Properties catalogProps = new Properties();
catalogProps.load(new FileInputStream(catalogConfigPath));

  
String appVersion = appProps.getProperty("version");
assertEquals("1.0", appVersion);
        
assertEquals("files", catalogProps.getProperty("c1"));

Пока содержимое файла соответствует требованиям к формату файла свойств, оно может быть правильно проанализировано классом Properties. Вот более подробная информация о формате файла свойств.

2.2. Загрузка из XML-файлов

Помимо файлов свойств, класс Properties также может загружать XML-файлы, которые соответствуют определенным спецификациям DTD.

Вот пример загрузки пар ключ-значение из файла XML – icons.xml:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <comment>xml example</comment>
    <entry key="fileIcon">icon1.jpg</entry>
    <entry key="imageIcon">icon2.jpg</entry>
    <entry key="videoIcon">icon3.jpg</entry>
</properties>

Теперь давайте загрузим его:

String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
String iconConfigPath = rootPath + "icons.xml";
Properties iconProps = new Properties();
iconProps.loadFromXML(new FileInputStream(iconConfigPath));

assertEquals("icon1.jpg", iconProps.getProperty("fileIcon"));

3. Получить свойства

Мы может использовать getProperty(String key) и getProperty(String key, String defaultValue) для получения значения по его ключу.

Если пара ключ-значение существует, оба метода вернут соответствующее значение. Но если такой пары ключ-значение нет, первый вернет null, а второй вместо этого вернет defaultValue.

Пример кода:

String appVersion = appProps.getProperty("version");
String appName = appProps.getProperty("name", "defaultName");
String appGroup = appProps.getProperty("group", "baeldung");
String appDownloadAddr = appProps.getProperty("downloadAddr");

assertEquals("1.0", appVersion);
assertEquals("TestApp", appName);
assertEquals("baeldung", appGroup);
assertNull(appDownloadAddr);

Обратите внимание, что хотя класс Properties наследует метод get() от класса Hashtable, я бы не рекомендовал вам использовать его для получения значения. Потому что его метод get() вернет значение Object, которое может быть приведено только к String, а метод getProperty() уже правильно обрабатывает необработанное значение Object.

Код ниже вызовет исключение:

float appVerFloat = (float) appProps.get("version");

4. Установка свойств

Мы можем использовать метод setProperty() для обновления существующей пары ключ-значение или добавления новой пары ключ-значение.

Пример кода:

appProps.setProperty("name", "NewAppName"); // update an old value
appProps.setProperty("downloadAddr", "www.baeldung.com/downloads"); // add new key-value pair

String newAppName = appProps.getProperty("name");
assertEquals("NewAppName", newAppName);
        
String newAppDownloadAddr = appProps.getProperty("downloadAddr");
assertEquals("www.baeldung.com/downloads", newAppDownloadAddr);

Обратите внимание, что хотя класс Properties наследует методы put() и putAll() от класса Hashtable, я бы не рекомендовал вам использовать их по той же причине, что и для метода get(): в свойствах можно использовать только строковые значения.

Код ниже не будет работать так, как вы хотите, когда вы используете getProperty() для получения его значения, он вернет null:

appProps.put("version", 2);

5. Удалить свойства

Если вы хотите удалить ключ- пары значений, вы можете использовать метод remove().

Пример кода:

String versionBeforeRemoval = appProps.getProperty("version");
assertEquals("1.0", versionBeforeRemoval);

appProps.remove("version");    
String versionAfterRemoval = appProps.getProperty("version");
assertNull(versionAfterRemoval);

6. Сохранить

6.1. Store to Properties Files

Класс Properties предоставляет метод store() для вывода пар ключ-значение.

Пример кода:

String newAppConfigPropertiesFile = rootPath + "newApp.properties";
appProps.store(new FileWriter(newAppConfigPropertiesFile), "store to properties file");

Второй параметр предназначен для комментария. Если вы не хотите писать комментарий, просто используйте для него null.

6.2. Store to XML Files

Класс свойств также предоставляет метод storeToXML() для вывода пар ключ-значение в формате XML.

Пример кода:

String newAppConfigXmlFile = rootPath + "newApp.xml";
appProps.storeToXML(new FileOutputStream(newAppConfigXmlFile), "store to xml file");

Второй параметр такой же, как в методе store().

7. Другие общие операции

Класс Properties также предоставляет некоторые другие методы для работы со свойствами.

Пример кода:

appProps.list(System.out); // list all key-value pairs

Enumeration<Object> valueEnumeration = appProps.elements();
while (valueEnumeration.hasMoreElements()) {
    System.out.println(valueEnumeration.nextElement());
}

Enumeration<Object> keyEnumeration = appProps.keys();
while (keyEnumeration.hasMoreElements()) {
    System.out.println(keyEnumeration.nextElement());
}

int size = appProps.size();
assertEquals(3, size);

8. Список свойств по умолчанию

Объект свойств может содержать другой объект свойств в качестве списка свойств по умолчанию. Список свойств по умолчанию будет искаться, если ключ свойства не найден в исходном списке.

Помимо «app.properties», у нас есть еще один файл — «default.properties» — в нашем пути к классам:

default.properties:

site=www.google.com
name=DefaultAppName
topic=Properties
category=core-java

Пример кода: ~~ ~

String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();

String defaultConfigPath = rootPath + "default.properties";
Properties defaultProps = new Properties();
defaultProps.load(new FileInputStream(defaultConfigPath));

String appConfigPath = rootPath + "app.properties";
Properties appProps = new Properties(defaultProps);
appProps.load(new FileInputStream(appConfigPath));

assertEquals("1.0", appVersion);
assertEquals("TestApp", appName);
assertEquals("www.google.com", defaultSite);

9. Свойства и кодировка

По умолчанию файлы свойств должны иметь кодировку ISO-8859-1 (Latin-1), поэтому свойства с символами, отличными от ISO-8859-1, обычно не должны использовал.

Мы можем обойти это ограничение с помощью таких инструментов, как JDK native2ascii или явной кодировки файлов, если это необходимо.

«Для файлов XML методы loadFromXML() и storeToXML() по умолчанию используют кодировку символов UTF-8.

Однако при чтении XML-файла, закодированного по-другому, мы можем указать это в объявлении DOCTYPE; запись также достаточно гибкая — мы можем указать кодировку в третьем параметре API storeToXML().

10. Заключение

В этой статье мы обсудили базовое использование класса Properties, в том числе то, как использовать свойства для загрузки и хранения пар ключ-значение как в свойствах, так и в формате XML, как работать с парами ключ-значение в свойствах. объекта, такие как получение значений, обновление значений, получение его размера и использование списка по умолчанию для объекта свойств.

Полный исходный код примера доступен в этом проекте GitHub.