Properties

Открыта

— Сегодня мы изучаем еще одну новую и интересную тему – свойства (properties).

Properties - 1

В Java принято делать программы гибкими и легко настраиваемыми. Иногда еще говорят легко конфигурируемыми (от конфигурация).

Например, твоя программа раз в час копирует файлы из некоторой директории, архивирует их и отсылает тебе на email. Для этого программе надо знать директорию, откуда брать файлы и email, куда их посылать. Такие данные принято хранить не в коде программы, а в отдельных файлах свойств – properties-файлах.

Данные в таком файле хранятся в виде пар ключ-значение, разделенные знаком равно.

Пример
Файл data.properties
directory=c:/text/downloads
email=zapp@javarush.ru

Слева от знака равно – имя (ключ), справа – значение.

— Т.е. это что-то типа текстового представления HashMap?

— В общем-то, да.

Для удобной работы с такими файлами в Java есть специальный класс – Properties. Класс Properties унаследован от Hashtable<Object,Object>. Его даже можно рассматривать как HashTable, который умеет загружать себя из файла.

Вот его методы:

Метод Описание
void load(Reader reader) Загружает свойства из файла, представленного объектом Reader
void load(InputStream inStream) Загружает свойства из файла, представленного объектом InputStream
void loadFromXML(InputStream in) Загружает свойства из XML-файла
Object get(Object key) Возвращает значение по ключу. Метод унаследован от HashTable
String getProperty(String key) Возвращает значение свойства (строку) по ключу
String getProperty(String key, String defaultValue) Возвращает значение свойства по ключу или defaultValue, если такого ключа нет
Set<String> stringPropertyNames() Возвращает список всех ключей

Т.е. фактически тебе нужно выполнить всего две операции – загрузить в объект Properties данные из какого-нибудь файла, а затем получить эти свойства с помощью метода getProperty(). Ну и не забывай, что можешь пользоваться объектом Properties как HashMap.

Вот тебе пример:

Код
//файл, который хранит свойства нашего проекта
File file = new File("c:/data.properties");

//создаем объект Properties и загружаем в него данные из файла.
Properties properties = new Properties();
properties.load(new FileReader(file));

//получаем значения свойств из объекта Properties
String email = properties.getProperty("email");
String directory = properties.getProperty("directory");

//получаем числовое значение из объекта Properties
int maxFileSize = Integer.parseInt(properties.getProperty("max.size", "10000"));

— Ага. Т.е. мы создаем объект Properties, затем передаем в него файл. В метод load, а затем просто вызываем getProperty. Так?

— Ага.

— А ты еще говорил, что им можно пользоваться как HashMap? Что ты имел в виду?

— Класс Properties унаследован от Hashtable, а это – тот же HashMap, просто все методы его синхронизированы. Вот так можно просто вывести на экран все значения из файла свойств:

Код
//получаем файл со свойствами
File file = new File("c:/data.properties");

//создаем объект Properties и загружаем в него данные из файла.
Properties properties = new Properties();
properties.load(new FileReader(file));

//проходимся по всем ключам и печатаем все их значения на консоль
for (String key : properties.stringPropertyNames())
{
 System.out.println(properties.get(key));
}

— Ага. Вроде все стало на свои места. Спасибо, Риша, буду пользоваться такой крутой штукой.

Комментарии (85)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Максим Li Backend Developer
30 ноября 2025, 00:39
✅
{Java_Shark}
Уровень 36
15 января 2025, 12:15
++
Suzuya Jūzō
Уровень 46
17 июня 2023, 16:33
Сегодня мы изучаем еще одну новую и интересную тему – свойства (properties) Да в каком месте она новая то? В двух предыдущих квестах уже была...
Петрович
Уровень 36
28 августа 2022, 18:10
Друзья, а почему мне null вернуло?
Alexey
Уровень 24
6 сентября 2022, 09:38
Содержимое файла какое?
Петрович
Уровень 36
7 сентября 2022, 05:20
не пустные....directory=c:/text/downloads email=zapp@javarush.ru .. как в примере
Alexey
Уровень 24
7 сентября 2022, 17:24
Сразу не заметил. Расширение файла должно быть не .txt ,а .properties
Петрович
Уровень 36
9 сентября 2022, 20:01
ха точно, спасибо=)
Евгений
Уровень 38
10 декабря 2022, 23:01
Ты вроде load не сделал
9 января 2023, 11:08
это прям важный момент? ТО есть с файла именно только с таким расширением будет рабтоать, а с любым другим нет?
4 декабря 2024, 08:02
а где загрузка файла? Пустая проперти, нужно загрузить файл, который тоже не создал
Lipovskyi Volodymyr
Уровень 36
12 августа 2022, 08:10
Ріша, та ми же вивчили вже Properties на останніх рівнях у JavaCore, як і більшість Patterns - "Почитайте у вікі про це"🤣
Ilia lenskii
Уровень 32
3 июля 2022, 11:30
Что касается примеров кода, то есть вот это getResourceAsStream + там же ссылка на docs.oracle.com
MyClass.getResourceAsStream("my.properties");
Где MyClass имя вашего класса, далее class и вызов непосредственно getResourceAsStream У меня это выглядит вот так вот
InputStream inpPror = Myprop.class.getResourceAsStream("../prp.properties");
 if(inpPror != null)  {
            Properties properties = new Properties();
            properties.load(inpPror);
}
Экономия на спичках
Артём
Уровень 28
21 февраля 2022, 15:28
а чем это отличается от сериализации?
Anonymous #3161756
Уровень 40
17 февраля 2023, 09:49
Собственно ни чем, просто видимо готовый инструмент со своими фишками)
LuneFoxJava Developer в BIFITExpert
19 декабря 2021, 11:44
Как мёд для ушей (глаз), я тоже все настраиваемые параметры всегда хранил в отдельных классах, чтобы не выискивать их в коде (сам додумался), а тут даже специальный файлик с ними забубенили.
AlukardVampire hunter в The HellsingExpert
24 декабря 2021, 13:13
Ты что тут забыл, иди на работу уже)
LuneFoxJava Developer в BIFITExpert
24 декабря 2021, 15:06
Сарказм принят)
Роман Кончалов Java Developer Expert
19 января 2022, 14:00
Какие, например, параметры?
LuneFoxJava Developer в BIFITExpert
19 января 2022, 22:59
Да какие угодно. Например, дефолтный размер окна, или шрифт, который исползует интерфейс, или путь к папке, откуда программа по умолчанию берёт файлы для работы.
Роман Кончалов Java Developer Expert
20 января 2022, 08:18
Но ведь если эти параметры используются только в одно месте, то достаточно объявить их в начале целевого класса как private final. Или были какие-то параметры, которые в нескольких местах использовались?
LuneFoxJava Developer в BIFITExpert
20 января 2022, 08:47
Я про то и говорю, что все параметры, которые могли бы быть записаны, как private final в куче разных классов я просто беру и выношу в отдельный класс с public static final полями, чтобы потом не искать их внутри кода в разных местах. Например, когда писал игры здесь, все строки, которые выводятся на экран, хранил в отдельном классе Strings. Например:
public static final String GAME_OVER_MESSAGE = "Вы проиграли!";
И если где-то вдруг хотел поправить описание или фразу, я просто лез в Strings, а не искал их в куче функционального кода с механикой игры. Никто не мешает хранить разные настраиваемые параметры разных классов точно так же.
Сергей
Уровень 22
9 февраля 2022, 02:58
а еще он хранится отдельно от собранного проекта, как можно хранить и иные конфо файлы. И поэтому их можно менять в любое время, если у тебя не хардкодед конечно же кругом в проекте.
Hidden #213 Урoвень 13 (Forever&Ever)
26 февраля 2022, 14:41
Нет, тебе точно пора уже на работу))) Я почти на том же уровне, но нифига не понимаю о чём вы говорите. Какие-то настраиваемые final параметры и специальный файл для них. Что?! Зачем?! 😅 И ты ещё говоришь, что сам к этому пришёл, без этой лекции...
LuneFoxJava Developer в BIFITExpert
26 февраля 2022, 15:57
Дык чего тут особенного, тема лекции как раз про это самое :) Пока я не мог пользоваться properties, их роль заменял отдельный класс со статическими переменными. Например, в properties можно положить такие данные:
game.message.start=Игра началась!
game.message.finish=Игра закончилась!
А потом подгружать этот файлик и обращаться к полям properties. Я делал так прямо в классе:
public static final String GAME_MESSAGE_START = "Игра началась!";
public static final String GAME_MESSAGE_FINISH = "Игра закончилась!";
Ну, и обращался не так
printMessage(properties.get("game.message.start"));
А вот так
printMessage(Strings.GAME_MESSAGE_START);
Только и всего :) А сам я к этому пришёл по нужде, потому что устал искать строки с текстом в куче кода, чтобы исправить опечатку или что-то перефразировать. Тем более если строк много в разных классах.
Ars
Уровень 41
15 ноября 2021, 14:21
Инфа по задаче: Среднее количество попыток для этой задачи 2.24. Всего эту задачу решили 7291 учеников.
LuneFoxJava Developer в BIFITExpert
19 декабря 2021, 11:42
Всё хорошо, только это не задача, а лекция.
Ars
Уровень 41
19 декабря 2021, 12:44
От блин. Но в задачу копировать не буду. Уже не актуальная инфа.
Anonymous #2620027
Уровень 47
13 ноября 2021, 14:46
Properties уже разбирались в Core. Что Collections, что Multithreading основательно разбавлены повторением пройденного материала... В большинстве случаев, бессистемно.
LuneFoxJava Developer в BIFITExpert
19 декабря 2021, 11:42
Я даже рад этому, потому что курс прохожу медленно, и всё забывается. Пока мой мозг чувствует сопротивление при решении задач, курс всё делает верно.
Ars
Уровень 41
19 декабря 2021, 12:48
Чтобы не забывалось, это надо использовать. И/или конспектировать. По идее так и заявлено, что в курсе много задачи и поэтому, всё хорошо запомнится. Только увы, на многие либо нет задач вообще, либо их пара штук. Вот если бы те же properties нет нет, да и всплывали бы в задачах, то они бы и не были забыты. А вот такое повторение теории без прилагающейся практики не спасёт ситуацию. Всё равно забудется, если не использовать.
LuneFoxJava Developer в BIFITExpert
19 декабря 2021, 13:39
Ещё кстати хорошая практика для запоминания - это чётко понимать, что и как происходит, тогда и заучивать насильно ничего не придётся. Не знаю, какой пример даже привести. Например, если однажды выучить последовательность цифр от 1 до 10, то не нужно для каждого этажа в 10-этажном доме запоминать, какой находится выше, а какой ниже, а ещё отдельно помнить, что ниже 1 этажа и выше 10 этажа этажей нет, ты просто пользуешься здравым смыслом. А забыть здравый смысл куда сложнее, чем таблицу с информацией :)
Ars
Уровень 41
19 декабря 2021, 14:23
Понимать - не значит запомнить. Я могу прекрасно понять, как работает какой-нибудь LinkedHashMap, понять какие у него методы, чем он отличается от обычных HashMap и LinkedList. Но если я его не использовал достаточное время чтобы он отложился у меня в голове, то когда он мне понадобится, я про просто не вспомню. Учитывая, что разных классов только в JDK, наверное, сотни и есть ещё десятки фреймвороков со своими классами, то какими здравомысленными эти классы не были просто понять их чтобы запомнить - не выйдет.
LuneFoxJava Developer в BIFITExpert
19 декабря 2021, 14:58
Тут уж не поспоришь. Помнить подробности применения сотен классов с тысячами методов просто нереально.