Что выведет код?
#Tasks
import java.util.stream.Stream;
public class Task030726 {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(1, 2, 3);
stream.forEach(System.out::print);
stream.forEach(System.out::print);
}
}
#Tasks
👍3
👍3
Какие новые методы появились в 🤓
Ответ:
В Java 9 добавлены:
Stream.iterate(T seed, Predicate hasNext, UnaryOperator next) — возможность задать условие остановки (усовершенствованный for-цикл).
takeWhile(Predicate) — берёт элементы, пока условие истинно, затем прерывает поток.
dropWhile(Predicate) — отбрасывает элементы, пока условие истинно, затем возвращает остаток.
Эти методы позволяют работать с бесконечными стримами и условными потоками без использования limit или filter с побочным эффектом. Они эффективны для частичной обработки потоков.
#собеседование
Stream API в Java 9? Ответ:
Stream.iterate(T seed, Predicate hasNext, UnaryOperator next) — возможность задать условие остановки (усовершенствованный for-цикл).
takeWhile(Predicate) — берёт элементы, пока условие истинно, затем прерывает поток.
dropWhile(Predicate) — отбрасывает элементы, пока условие истинно, затем возвращает остаток.
Эти методы позволяют работать с бесконечными стримами и условными потоками без использования limit или filter с побочным эффектом. Они эффективны для частичной обработки потоков.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
История технологии сегодня — 4 июля
ℹ️ Кто родился в этот день
Жан-Пьер Франсуа Бланшар (фр. Jean Pierre François Blanchard; 4 июля 1753 — 7 марта 1809) — французский изобретатель, наиболее известен как пионер воздухоплавания. Совершил свой первый успешный полёт на воздушном шаре 2 марта 1784 года в Париже, на заполненном водородом воздушном шаре на Марсовом поле.
🌐 Знаковые события
2012 — официально объявлено об открытии в ЦЕРНе новой частицы, по свойствам похожей на предсказанный бозон Хиггса.
#Biography #Birth_Date #Events #04июля
Жан-Пьер Франсуа Бланшар (фр. Jean Pierre François Blanchard; 4 июля 1753 — 7 марта 1809) — французский изобретатель, наиболее известен как пионер воздухоплавания. Совершил свой первый успешный полёт на воздушном шаре 2 марта 1784 года в Париже, на заполненном водородом воздушном шаре на Марсовом поле.
2012 — официально объявлено об открытии в ЦЕРНе новой частицы, по свойствам похожей на предсказанный бозон Хиггса.
#Biography #Birth_Date #Events #04июля
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣5🔥1
Please open Telegram to view this post
VIEW IN TELEGRAM
История технологии сегодня — 5 июля
ℹ️ Кто родился в этот день
Ю́рис Ха́ртманис (латыш. Juris Hartmanis; 5 июля 1928, Рига — 29 июля 2022) — учёный в области теории вычислительных систем, награждён в 1993 году премией Тьюринга за достижения в исследовании теории сложности вычислений.
Уильям Джон Макуорн Ранкин (Ренкин) (англ. William John Macquorn Rankine; 5 июля 1820, Эдинбург — 24 декабря 1872, Глазго) — шотландский инженер, физик и механик, один из создателей технической термодинамики. В 1849 году независимо от Клаузиуса получил общие уравнения термодинамики, выражающие соотношение между количеством теплоты и механической энергией. Исследовал термодинамические свойства газов и пара в 1850 году и составил таблицы водяных паров получивших широкое применение. В 1859 году построил полную теорию паровой машины; в частности, разработал идеальный термодинамический цикл парового двигателя, названного в его честь.
Ге́рард Хо́фт (Герард эт Хоофт, нид. Gerardus (Gerard) ’t Hooft; род. 5 июля 1946, Ден-Хелдер, Северная Голландия) — голландский физик-теоретик, профессор Утрехтского университета (Нидерланды), лауреат Нобелевской премии по физике за 1999 год (совместно с Мартинусом Велтманом). Разработанные Хофтом и Велтманом математические методы ренормализации янг-миллсовских полей, как безмассовых, так и получающих массу вследствие спонтанного нарушения симметрии, позволили рассчитать некоторые эффекты электрослабого взаимодействия, в частности, оценить массы промежуточных векторных бозонов W± и Z0, предсказанных теорией и вскоре после этого открытых экспериментально, причём полученные значения хорошо согласовывались с экспериментальными данными. Методом Велтмана и Хофта также была рассчитана масса топ-кварка, экспериментально обнаруженного в 1995 году в Национальной лаборатории им. Э. Ферми (США).
🌐 Знаковые события
1996 — в Великобритании родилось первое клонированное млекопитающее — овца Долли
2016 — автоматическая межпланетная станция НАСА «Юнона», запущенная в 2011 году, вышла на полярную орбиту Юпитера.
#Biography #Birth_Date #Events #05июля
Ю́рис Ха́ртманис (латыш. Juris Hartmanis; 5 июля 1928, Рига — 29 июля 2022) — учёный в области теории вычислительных систем, награждён в 1993 году премией Тьюринга за достижения в исследовании теории сложности вычислений.
Уильям Джон Макуорн Ранкин (Ренкин) (англ. William John Macquorn Rankine; 5 июля 1820, Эдинбург — 24 декабря 1872, Глазго) — шотландский инженер, физик и механик, один из создателей технической термодинамики. В 1849 году независимо от Клаузиуса получил общие уравнения термодинамики, выражающие соотношение между количеством теплоты и механической энергией. Исследовал термодинамические свойства газов и пара в 1850 году и составил таблицы водяных паров получивших широкое применение. В 1859 году построил полную теорию паровой машины; в частности, разработал идеальный термодинамический цикл парового двигателя, названного в его честь.
Ге́рард Хо́фт (Герард эт Хоофт, нид. Gerardus (Gerard) ’t Hooft; род. 5 июля 1946, Ден-Хелдер, Северная Голландия) — голландский физик-теоретик, профессор Утрехтского университета (Нидерланды), лауреат Нобелевской премии по физике за 1999 год (совместно с Мартинусом Велтманом). Разработанные Хофтом и Велтманом математические методы ренормализации янг-миллсовских полей, как безмассовых, так и получающих массу вследствие спонтанного нарушения симметрии, позволили рассчитать некоторые эффекты электрослабого взаимодействия, в частности, оценить массы промежуточных векторных бозонов W± и Z0, предсказанных теорией и вскоре после этого открытых экспериментально, причём полученные значения хорошо согласовывались с экспериментальными данными. Методом Велтмана и Хофта также была рассчитана масса топ-кварка, экспериментально обнаруженного в 1995 году в Национальной лаборатории им. Э. Ферми (США).
1996 — в Великобритании родилось первое клонированное млекопитающее — овца Долли
2016 — автоматическая межпланетная станция НАСА «Юнона», запущенная в 2011 году, вышла на полярную орбиту Юпитера.
#Biography #Birth_Date #Events #05июля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
История технологии сегодня — 6 июля
ℹ️ Кто родился в этот день
Бори́с Па́влович Константи́нов (23 июня (6 июля) 1910, Санкт-Петербург — 9 июля 1969, Ленинград) — советский учёный, физик-ядерщик, академик (с 1960; член-корреспондент с 1953), вице-президент Академии наук СССР (c 8 февраля 1966 по 9 июля 1969). Работы посвящены акустике, физической химии, физике изотопов, физике плазмы и проблеме управляемого термоядерного синтеза, астрофизике, голографии. В ФТИ им. А. Ф. Иоффе основал астрофизическую лабораторию и филиал ядерной физики (впоследствии ПИЯФ).
🌐 Знаковые события
1926 — в СССР открыта первая электрифицированная линия железной дороги (Баку-Сабунчи).
2003 — с помощью радиотелескопа РТ-70 под Евпаторией был передан Космический зов — кодированное послание к нескольким звёздам солнечного типа.
#Biography #Birth_Date #Events #06июля
Бори́с Па́влович Константи́нов (23 июня (6 июля) 1910, Санкт-Петербург — 9 июля 1969, Ленинград) — советский учёный, физик-ядерщик, академик (с 1960; член-корреспондент с 1953), вице-президент Академии наук СССР (c 8 февраля 1966 по 9 июля 1969). Работы посвящены акустике, физической химии, физике изотопов, физике плазмы и проблеме управляемого термоядерного синтеза, астрофизике, голографии. В ФТИ им. А. Ф. Иоффе основал астрофизическую лабораторию и филиал ядерной физики (впоследствии ПИЯФ).
1926 — в СССР открыта первая электрифицированная линия железной дороги (Баку-Сабунчи).
2003 — с помощью радиотелескопа РТ-70 под Евпаторией был передан Космический зов — кодированное послание к нескольким звёздам солнечного типа.
#Biography #Birth_Date #Events #06июля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
[Совет по Java #057]
Тема:
Проблема:
Решение: В пулах потоков избегайте использования
Объяснение:
В пулах потоков потоки создаются один раз и затем переиспользуются, поэтому наследование происходит только при инициализации пула. Если пул создан в главном потоке, то все задачи унаследуют контекст главного потока, а не контекст того потока, который отправил задачу. Если пул создается внутри задачи, то все потоки пула унаследуют контекст этой задачи, что также нежелательно. Таким образом,
#Java #советы
Тема:
ThreadLocal с InheritableThreadLocal опасен для пулов потоков.Проблема:
InheritableThreadLocal расширяет ThreadLocal и позволяет передавать значения из родительского потока в дочерний при создании нового потока. В средах с пулами потоков (например, ExecutorService, веб-контейнеры) потоки не создаются заново для каждой задачи, а переиспользуются. При использовании InheritableThreadLocal значения наследуются от потока, который создал пул (обычно главный поток приложения), а не от того, который поставил задачу. Это приводит к тому, что все задачи в пуле получают один и тот же контекст, либо, если пул был создан внутри другой задачи, дочерние задачи могут унаследовать контекст от случайной родительской задачи. В результате происходит утечка контекста безопасности, идентификатора пользователя, транзакционных данных и т.п., что приводит к непредсказуемому поведению и серьезным уязвимостям.Решение: В пулах потоков избегайте использования
InheritableThreadLocal. Если нужно передать контекст, используйте явные параметры в методах или передавайте контекст через ThreadLocal с ручной установкой и обязательной очисткой в блоке try-finally. Для безопасной передачи контекста между задачами в пулах применяйте ThreadLocal и устанавливайте его значение перед выполнением задачи, очищая после. В высоконагруженных системах рассмотрите использование ScopedValue (Java 21+), который предназначен для передачи значений без утечек. Никогда не полагайтесь на автоматическое наследование в пулах потоков.public class InheritableThreadLocalPitfall {
//Опасно: InheritableThreadLocal в пуле
private static final InheritableThreadLocal<String> USER_CONTEXT =
new InheritableThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(2);
// Главный поток устанавливает контекст
USER_CONTEXT.set("Admin");
// Задача, которая пытается получить унаследованное значение
executor.submit(() -> {
// Выведет "Admin", даже если ожидается другой контекст
System.out.println("Task 1 - inherited: " + USER_CONTEXT.get());
});
// Меняем контекст перед новой задачей в главном потоке
USER_CONTEXT.set("Guest");
executor.submit(() -> {
// Выведет "Guest" (текущее значение главного потока)
System.out.println("Task 2 - inherited: " + USER_CONTEXT.get());
});
// В реальности пул создан один раз, и значения берутся из главного
// потока в момент создания пула или подачи задачи? На самом деле
// наследование происходит при создании потока, а не при submit.
// В данном примере потоки уже созданы, поэтому унаследованных значений нет.
// Это показывает, что наследование происходит только при создании потока.
// Если создать новый пул внутри другой задачи, то контекст унаследуется
// от родительской задачи, что тоже опасно.
executor.shutdown();
}
}//Безопасный подход: явная передача контекста
public class SafeThreadLocal {
private static final ThreadLocal<String> CONTEXT = new ThreadLocal<>();
public static void executeWithContext(ExecutorService executor,
String user, Runnable task) {
executor.submit(() -> {
try {
CONTEXT.set(user);
task.run();
} finally {
CONTEXT.remove(); // обязательная очистка
}
});
}
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
executeWithContext(executor, "Admin", () -> {
System.out.println("Working as: " + CONTEXT.get());
});
executor.shutdown();
}
}
Объяснение:
InheritableThreadLocal работает только в момент создания нового потока — он копирует значения из родительского потока в новый поток. В пулах потоков потоки создаются один раз и затем переиспользуются, поэтому наследование происходит только при инициализации пула. Если пул создан в главном потоке, то все задачи унаследуют контекст главного потока, а не контекст того потока, который отправил задачу. Если пул создается внутри задачи, то все потоки пула унаследуют контекст этой задачи, что также нежелательно. Таким образом,
InheritableThreadLocal нарушает принцип изоляции задач в пуле. Правильный подход — явно устанавливать контекст для каждой задачи и обязательно очищать его после выполнения, чтобы избежать утечек между задачами в одном потоке. Начиная с Java 21, ScopedValue предоставляет безопасную альтернативу для передачи значений, которая автоматически очищается.#Java #советы
👍4
Что выведет код?
#Tasks
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Task060726 {
private static final InheritableThreadLocal<String> threadLocal = new InheritableThreadLocal<>();
public static void main(String[] args) {
threadLocal.set("main");
ExecutorService executor = Executors.newFixedThreadPool(1);
for (int i = 0; i < 3; i++) {
final int taskId = i;
executor.submit(() -> {
if (threadLocal.get() == null) {
threadLocal.set("task" + taskId);
}
System.out.print(threadLocal.get() + " ");
});
}
executor.shutdown();
}
}
#Tasks
👍3
Варианты ответа:
Anonymous Quiz
43%
main main main
21%
task0 task1 task2
29%
task0 task0 task0
7%
null null null
👍3
Что такое 🤓
Ответ:
В Java 9 добавлены новые методы Optional:
ifPresentOrElse(Consumer action, Runnable emptyAction) — выполняет одно действие, если значение есть, и другое, если отсутствует.
or(Supplier<Optional>) — позволяет "подменить" пустой Optional другим Optional. Также в Java 10 появился orElseThrow() (который стал синонимом get()).
Эти методы делают работу с Optional более функциональной и избавляют от использования isPresent()/get(), что считается анти-паттерном.
#собеседование
Optional.ifPresentOrElse() и Optional.or()? Ответ:
ifPresentOrElse(Consumer action, Runnable emptyAction) — выполняет одно действие, если значение есть, и другое, если отсутствует.
or(Supplier<Optional>) — позволяет "подменить" пустой Optional другим Optional. Также в Java 10 появился orElseThrow() (который стал синонимом get()).
Эти методы делают работу с Optional более функциональной и избавляют от использования isPresent()/get(), что считается анти-паттерном.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
История технологии сегодня — 7 июля
ℹ️ Кто родился в этот день
Ю́рий Серге́евич О́сипов (род. 7 июля 1936, Тобольск) — советский и российский математик и механик, профессор. Специалист в области прикладной математики и механики. Основные научные исследования посвящены теории управления, дифференциальным уравнениям и их приложениям.
Создал законченную теорию стабилизации стационарных и периодических динамических систем, описываемых дифференциальными уравнениями с запаздывающим аргументом.
Разработал теорию дифференциальных игр для динамических систем с запаздывающим аргументом.
Открыл конструктивный локальный принцип управления системами с запаздыванием.
Построил теорию антагонистических позиционных дифференциальных игр для другого класса конфликтно управляемых систем с бесконечномерными пространствами фазовых состояний — систем, описываемых дифференциальными уравнениями с частными производными, в первую очередь параболическими.
Цикл работ посвящён созданию теории устойчивого динамического обращения управляемых систем.
Получил серию результатов в смежных направлениях: им выполнен ряд работ по оптимизации форм, в одной из которых был, в частности, дан ответ на вопрос о существовании оптимума, поставленный Ж.-Л. Лионсом.
🌐 Знаковые события
1891 — компания «Американ Экспресс» запатентовала дорожные чеки, послужившие прообразом современных кредитных карт.
#Biography #Birth_Date #Events #07июля
Ю́рий Серге́евич О́сипов (род. 7 июля 1936, Тобольск) — советский и российский математик и механик, профессор. Специалист в области прикладной математики и механики. Основные научные исследования посвящены теории управления, дифференциальным уравнениям и их приложениям.
Создал законченную теорию стабилизации стационарных и периодических динамических систем, описываемых дифференциальными уравнениями с запаздывающим аргументом.
Разработал теорию дифференциальных игр для динамических систем с запаздывающим аргументом.
Открыл конструктивный локальный принцип управления системами с запаздыванием.
Построил теорию антагонистических позиционных дифференциальных игр для другого класса конфликтно управляемых систем с бесконечномерными пространствами фазовых состояний — систем, описываемых дифференциальными уравнениями с частными производными, в первую очередь параболическими.
Цикл работ посвящён созданию теории устойчивого динамического обращения управляемых систем.
Получил серию результатов в смежных направлениях: им выполнен ряд работ по оптимизации форм, в одной из которых был, в частности, дан ответ на вопрос о существовании оптимума, поставленный Ж.-Л. Лионсом.
1891 — компания «Американ Экспресс» запатентовала дорожные чеки, послужившие прообразом современных кредитных карт.
#Biography #Birth_Date #Events #07июля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Раздел 11. Работа с файлами, I/O и сетью (NIO.2)
Глава 2. Современный NIO.2 (java.nio.file)
Интерфейс
Интерфейс
Что такое Path
Path (от англ. "путь") — это интерфейс, представляющий иерархическое расположение файла или директории в файловой системе. Главное отличие от старого
Абстракция — в программировании это способ представления сложной реальности в упрощённом виде, скрывая детали реализации.
Создание объекта Path
Основной способ создания — статический метод фабрики
Способ 1: единая строка пути
При передаче строки с обратными слешами в Windows
Способ 2: сегменты пути (varargs)
Этот способ удобен при динамической сборке пути из частей. Метод
Способ 3: относительный путь
Относительный путь строится относительно текущей рабочей директории JVM — это директория, из которой был запущен процесс Java.
Способ 4: через FileSystem
Ключевые методы интерфейса Path
toString() — строковое представление
Метод возвращает строку пути в нативном формате ОС. Это не просто геттер — он выполняет конкатенацию сегментов с правильным разделителем.
getFileName() — имя файла или последняя директория
Возвращает последний сегмент пути как новый объект
getParent() — родительская директория
Возвращает путь без последнего сегмента. Если у пути нет родителя (корень или относительный путь из одного сегмента), возвращает
getRoot() — корневая часть пути
Для абсолютного пути возвращает корневой элемент (
getNameCount() — количество сегментов
Возвращает число имен (сегментов) в пути, исключая корень. Корень не считается именем — это отправная точка иерархии.
getName(int index) — сегмент по индексу
Индексация начинается с 0. Индекс
subpath(int beginIndex, int endIndex) — подпуть
Возвращает подпуть от
isAbsolute() — проверка на абсолютность
Абсолютный путь содержит корневой элемент и однозначно указывает местоположение в файловой системе. Относительный — зависит от текущей директории.
toAbsolutePath() — преобразование в абсолютный
Если путь уже абсолютный — возвращает себя. Иначе резолвит относительно текущей рабочей директории.
normalize() — нормализация пути
Удаляет избыточные сегменты:
resolve(Path other) — резолюция пути
Если
relativize(Path other) — относительный путь между двумя путями
Вычисляет, как добраться от
startsWith(Path other) / endsWith(Path other)
Сравнивают сегменты пути, а не строки.
#Java #для_новичков #beginner #IO #NIO #Path
Глава 2. Современный NIO.2 (java.nio.file)
Интерфейс
Path – путь к файлу/директорииИнтерфейс
Path — это ключевая абстракция в Java NIO.2 (New I/O 2), представленная в Java 7 (2011 год, пакет java.nio.file). Он заменил устаревший класс java.io.File и предоставляет платформонезависимый способ работы с путями к файлам и директориям. В отличие от File, который напрямую обращался к файловой системе ОС, Path — это чистая абстракция: объект Path может существовать в памяти JVM, даже если соответствующего файла на диске нет.Что такое Path
Path (от англ. "путь") — это интерфейс, представляющий иерархическое расположение файла или директории в файловой системе. Главное отличие от старого
File в том, что Path — это не файл, а именно путь. Он не знает, существует ли файл, доступен ли он для чтения, и т.д. — эти вопросы решаются через другие классы NIO.2, например Files.Абстракция — в программировании это способ представления сложной реальности в упрощённом виде, скрывая детали реализации.
Path абстрагирует различия между файловыми системами: в Windows путь разделяется обратным слешем C:\Users\file.txt, в Linux и macOS — прямым /home/user/file.txt. Path нормализует эти различия на уровне API.Создание объекта Path
Основной способ создания — статический метод фабрики
Paths.get(). Класс Paths (во множественном числе) — это утилитарный класс-фабрика, который делегирует создание Path текущей файловой системе по умолчанию.Способ 1: единая строка пути
import java.nio.file.Path;
import java.nio.file.Paths;
// Linux / macOS
Path linuxPath = Paths.get("/home/user/documents/report.txt");
// Windows
Path windowsPath = Paths.get("C:\\Users\\Admin\\file.txt");
При передаче строки с обратными слешами в Windows
Paths.get() корректно парсит путь. Важно: в Java-строке обратный слеш — это escape-символ, поэтому в литерале пишется \\, но при чтении из внешнего источника (конфиг, ввод пользователя) это не требуется.Способ 2: сегменты пути (varargs)
Path path = Paths.get("/home", "user", "documents", "report.txt");
// Результат: /home/user/documents/report.txtЭтот способ удобен при динамической сборке пути из частей. Метод
get(String first, String... more) принимает первый сегмент и переменное число дополнительных сегментов (varargs — механизм Java для передачи произвольного количества аргументов одного типа). Сегменты автоматически соединяются разделителем, специфичным для ОС.Способ 3: относительный путь
Path relative = Paths.get("src", "main", "java", "App.java");
// Результат: src/main/java/App.java (на Unix) или src\main\java\App.java (на Windows)Относительный путь строится относительно текущей рабочей директории JVM — это директория, из которой был запущен процесс Java.
Способ 4: через FileSystem
import java.nio.file.FileSystems;
Path path = FileSystems.getDefault().getPath("/tmp", "data.txt");
FileSystems.getDefault() возвращает объект FileSystem — абстракцию над конкретной файловой системой. Этот подход используется при работе с нестандартными файловыми системами (например, ZIP-архив как файловая система через FileSystems.newFileSystem()).Ключевые методы интерфейса Path
toString() — строковое представление
Path p = Paths.get("/home/user/file.txt");
System.out.println(p.toString());
// Вывод: /home/user/file.txtМетод возвращает строку пути в нативном формате ОС. Это не просто геттер — он выполняет конкатенацию сегментов с правильным разделителем.
getFileName() — имя файла или последняя директория
Path p = Paths.get("/home/user/documents/report.txt");
Path fileName = p.getFileName(); // report.txt
Path dir = Paths.get("/home/user/documents");
Path dirName = dir.getFileName(); // documentsВозвращает последний сегмент пути как новый объект
Path. Если путь — корень (/), возвращает null.getParent() — родительская директория
Path p = Paths.get("/home/user/documents/report.txt");
Path parent = p.getParent(); // /home/user/documents
Path root = Paths.get("/");
Path rootParent = root.getParent(); // nullВозвращает путь без последнего сегмента. Если у пути нет родителя (корень или относительный путь из одного сегмента), возвращает
null.getRoot() — корневая часть пути
Path absolute = Paths.get("/home/user/file.txt");
Path root = absolute.getRoot(); // /
Path relative = Paths.get("src/main/java");
Path relRoot = relative.getRoot(); // nullДля абсолютного пути возвращает корневой элемент (
/ на Unix, C:\ на Windows). Для относительного — null, так как корень не определён.getNameCount() — количество сегментов
Path p = Paths.get("/home/user/documents/report.txt");
int count = p.getNameCount(); // 4 (home, user, documents, report.txt)Возвращает число имен (сегментов) в пути, исключая корень. Корень не считается именем — это отправная точка иерархии.
getName(int index) — сегмент по индексу
Path p = Paths.get("/home/user/documents/report.txt");
Path segment = p.getName(1); // userИндексация начинается с 0. Индекс
0 — первый сегмент после корня. Выход за границы выбрасывает IllegalArgumentException.subpath(int beginIndex, int endIndex) — подпуть
Path p = Paths.get("/home/user/documents/report.txt");
Path sub = p.subpath(1, 3); // user/documentsВозвращает подпуть от
beginIndex (включительно) до endIndex (исключительно). Индексы отсчитываются от корня, но сам корень в результат не включается.isAbsolute() — проверка на абсолютность
Path abs = Paths.get("/etc/passwd");
boolean isAbs = abs.isAbsolute(); // true
Path rel = Paths.get("config/app.properties");
boolean isRel = rel.isAbsolute(); // falseАбсолютный путь содержит корневой элемент и однозначно указывает местоположение в файловой системе. Относительный — зависит от текущей директории.
toAbsolutePath() — преобразование в абсолютный
Path rel = Paths.get("config/app.properties");
Path abs = rel.toAbsolutePath();
// Результат: /current/working/dir/config/app.propertiesЕсли путь уже абсолютный — возвращает себя. Иначе резолвит относительно текущей рабочей директории.
normalize() — нормализация пути
Path p = Paths.get("/home/user/../documents/./report.txt");
Path norm = p.normalize(); // /home/documents/report.txtУдаляет избыточные сегменты:
. (текущая директория) и .. (родительская директория). Не проверяет реальное существование файловой системы — работает чисто на уровне строк.resolve(Path other) — резолюция пути
Path base = Paths.get("/home/user");
Path resolved = base.resolve("documents/report.txt");
// Результат: /home/user/documents/report.txtЕсли
other абсолютный — возвращает other. Если относительный — присоединяет к base. Эквивалент операции "base/other".relativize(Path other) — относительный путь между двумя путями
Path base = Paths.get("/home/user");
Path target = Paths.get("/home/user/documents/report.txt");
Path rel = base.relativize(target); // documents/report.txtВычисляет, как добраться от
base до target относительным путём. Оба пути должны быть либо абсолютными, либо относительными.startsWith(Path other) / endsWith(Path other)
Path p = Paths.get("/home/user/documents");
boolean starts = p.startsWith(Paths.get("/home")); // true
boolean ends = p.endsWith(Paths.get("documents")); // trueСравнивают сегменты пути, а не строки.
startsWith проверяет, начинается ли путь с указанных сегментов с учётом иерархии.#Java #для_новичков #beginner #IO #NIO #Path
👍4
toFile() — обратная совместимость
Преобразует Path в старый java.io.File. Полезно при интеграции с legacy-кодом или библиотеками, которые ещё не перешли на NIO.2.
iterator() — итерация по сегментам
Path реализует Iterable<Path>, что позволяет использовать for-each для обхода сегментов. Корень в итерацию не включается.
compareTo(Path other) — лексикографическое сравнение
Сравнивает пути посегментно, учитывая регистр (на системах с case-sensitive файловыми системами). Реализует
Путь байтов в памяти JVM при работе с Path
Когда вы пишете Paths.get("/home/user/file.txt"), в памяти JVM происходит следующее:
1. Создание строки в пуле строк (String Pool)
Литерал
При компиляции он попадает в пул строк (String Pool) — специальная область в Metaspace (начиная с Java 8; ранее — PermGen).
Пул строк — это кэш строковых литералов, где одинаковые строки представлены единственным экземпляром. Это экономит память, так как строки в Java иммутабельны (неизменяемы).
Metaspace — область памяти JVM, выделенная под метаданные классов, константы, пул строк и другие внутренние структуры.
В отличие от старого PermGen, Metaspace использует нативную память (native memory) вне кучи и расширяется динамически.
2. Вызов Paths.get() и создание объекта Path
Метод
Файловая система по умолчанию (обычно
Эти объекты создаются в куче (Heap) — основной области памяти для объектов Java.
Объект
Ссылку на файловую систему (
Массив байтов или строк, представляющих сегменты пути
Хэш-код для кэширования
3. Работа GC с объектами Path
Объекты
GC (Garbage Collector, сборщик мусора) — это механизм JVM, автоматически освобождающий память от объектов, на которые больше нет ссылок.
Когда переменная
Однако сама строка-путь в пуле строк остаётся — пул строк не подлежит обычной сборке мусора, так как JVM предполагает, что строковые литералы могут понадобиться снова.
Если
Young Generation — часть кучи, где размещаются новые объекты. Она делится на Eden (пространство, куда попадают все новые объекты) и два Survivor-пространства (S0, S1). Когда Eden заполняется, запускается Minor GC — быстрая сборка мусора, перемещающая живые объекты в Survivor. Объекты
Если объект
Важно:
4. Байты на уровне ОС
Когда
#Java #для_новичков #beginner #IO #NIO #Path
Path path = Paths.get("/tmp/data.txt");
java.io.File legacyFile = path.toFile();Преобразует Path в старый java.io.File. Полезно при интеграции с legacy-кодом или библиотеками, которые ещё не перешли на NIO.2.
iterator() — итерация по сегментам
Path p = Paths.get("/home/user/file.txt");
for (Path segment : p) {
System.out.println(segment);
}
// Вывод: home, user, file.txtPath реализует Iterable<Path>, что позволяет использовать for-each для обхода сегментов. Корень в итерацию не включается.
compareTo(Path other) — лексикографическое сравнение
Path p1 = Paths.get("/a/b/c");
Path p2 = Paths.get("/a/b/d");
int result = p1.compareTo(p2); // отрицательное число (c < d)Сравнивает пути посегментно, учитывая регистр (на системах с case-sensitive файловыми системами). Реализует
Comparable<Path>, что позволяет сортировать пути.Путь байтов в памяти JVM при работе с Path
Когда вы пишете Paths.get("/home/user/file.txt"), в памяти JVM происходит следующее:
1. Создание строки в пуле строк (String Pool)
Литерал
"/home/user/file.txt" — это объект String. При компиляции он попадает в пул строк (String Pool) — специальная область в Metaspace (начиная с Java 8; ранее — PermGen).
Пул строк — это кэш строковых литералов, где одинаковые строки представлены единственным экземпляром. Это экономит память, так как строки в Java иммутабельны (неизменяемы).
Metaspace — область памяти JVM, выделенная под метаданные классов, константы, пул строк и другие внутренние структуры.
В отличие от старого PermGen, Metaspace использует нативную память (native memory) вне кучи и расширяется динамически.
2. Вызов Paths.get() и создание объекта Path
Метод
Paths.get() вызывает FileSystems.getDefault().getPath(first, more). Файловая система по умолчанию (обычно
UnixFileSystem на Linux/macOS или WindowsFileSystem на Windows) создаёт конкретную реализацию Path — например, UnixPath или WindowsPath.Эти объекты создаются в куче (Heap) — основной области памяти для объектов Java.
Объект
Path хранит:Ссылку на файловую систему (
FileSystem)Массив байтов или строк, представляющих сегменты пути
Хэш-код для кэширования
3. Работа GC с объектами Path
Объекты
Path — это обычные Java-объекты в куче. GC (Garbage Collector, сборщик мусора) — это механизм JVM, автоматически освобождающий память от объектов, на которые больше нет ссылок.
Когда переменная
Path выходит из области видимости (например, метод завершился, и локальная переменная недоступна), объект становится кандидатом на сборку мусора. Однако сама строка-путь в пуле строк остаётся — пул строк не подлежит обычной сборке мусора, так как JVM предполагает, что строковые литералы могут понадобиться снова.
Если
Path создаётся динамически (например, Paths.get(base, userInput)), и входные данные уникальны при каждом вызове, строки не попадают в пул автоматически (если только не вызван intern()). Такие строки создаются в куче и полностью управляются GC. При частом создании временных путей (например, в цикле обработки 10 000 файлов) объекты Path и связанные строки накапливаются в Young Generation (молодое поколение) кучи.Young Generation — часть кучи, где размещаются новые объекты. Она делится на Eden (пространство, куда попадают все новые объекты) и два Survivor-пространства (S0, S1). Когда Eden заполняется, запускается Minor GC — быстрая сборка мусора, перемещающая живые объекты в Survivor. Объекты
Path, созданные внутри короткоживущего метода, обычно уничтожаются на этом этапе.Если объект
Path кэшируется (например, сохраняется в статическое поле или долгоживущую коллекцию), он переходит в Old Generation (старое поколение, Tenured). Там он живёт до Major GC (или Full GC) — более тяжёлой сборки, которая затрагивает всю кучу. Major GC запускается, когда Old Generation заполняется.Важно:
Path — лёгкий объект. Он не держит открытых файловых дескрипторов (в отличие от FileInputStream). Поэтому его сборка мусора безопасна в любой момент. Однако если Path используется для открытия ресурса (через Files.newInputStream(path)), то сам поток уже требует явного закрытия через try-with-resources, иначе дескриптор останется открытым на уровне ОС, даже если объект Path собран GC.4. Байты на уровне ОС
Когда
Path передаётся в метод Files.readAllBytes(path), JVM через JNI (Java Native Interface — механизм вызова нативного кода) обращается к системному вызову ОС. Путь преобразуется в массив байтов в кодировке, понятной файловой системе (обычно UTF-8). Эти байты передаются в системный вызов open() (POSIX) или CreateFile() (Windows). Прочитанные данные возвращаются в JVM как массив байтов в куче (heap-allocated byte array).#Java #для_новичков #beginner #IO #NIO #Path
👍5
Интеграции и практические примеры
Пример 1: Обход директории с фильтрацией
Пример 2: Резолюция путей в конфигурации приложения
Этот паттерн защищает от Path Traversal (атака обхода пути), когда злоумышленник передаёт
Пример 3: Копирование с проверкой
Пример 4: Работа с временными файлами
Path vs File: ключевые различия
Класс java.io.File (существует с Java 1.0) имеет ряд архитектурных недостатков:
Смешение ответственности:
Ограниченная поддержка символических ссылок:
Отсутствие нормализации:
Нет поддержки файловых систем, отличных от дефолтной:
Методы
#Java #для_новичков #beginner #IO #NIO #Path
Пример 1: Обход директории с фильтрацией
import java.nio.file.*;
import java.io.IOException;
public class DirectoryScanner {
public static void scanDirectory(Path root) throws IOException {
// Files.walk — рекурсивный обход дерева директорий
try (Stream<Path> paths = Files.walk(root, 3)) { // глубина 3 уровня
paths.filter(Files::isRegularFile) // только файлы
.filter(p -> p.toString().endsWith(".java"))
.forEach(p -> System.out.println(p.toAbsolutePath()));
}
}
}
Files.walk() возвращает Stream<Path> — ленивый поток (lazy stream), который читает директории по мере необходимости. Это предотвращает загрузку всех путей в память сразу, что критично для больших файловых деревьев.Пример 2: Резолюция путей в конфигурации приложения
public class ConfigResolver {
private final Path baseDir;
public ConfigResolver(String basePath) {
this.baseDir = Paths.get(basePath).toAbsolutePath().normalize();
}
public Path resolveConfig(String configName) {
// resolve объединяет baseDir с относительным путём
Path resolved = baseDir.resolve("config").resolve(configName);
// безопасность: проверяем, что результирующий путь всё ещё внутри baseDir
if (!resolved.startsWith(baseDir)) {
throw new SecurityException("Path traversal attempt detected");
}
return resolved;
}
}Этот паттерн защищает от Path Traversal (атака обхода пути), когда злоумышленник передаёт
../../../etc/passwd в качестве configName. Метод startsWith() гарантирует, что результирующий путь остаётся внутри разрешённой директории.Пример 3: Копирование с проверкой
public void safeCopy(Path source, Path target) throws IOException {
// normalize убирает . и .. перед проверкой
Path normalizedSource = source.toAbsolutePath().normalize();
Path normalizedTarget = target.toAbsolutePath().normalize();
// getParent возвращает директорию назначения
Path targetDir = normalizedTarget.getParent();
if (targetDir != null && !Files.exists(targetDir)) {
Files.createDirectories(targetDir); // создаём всю цепочку директорий
}
// StandardCopyOption — перечисление, определяющее поведение копирования
Files.copy(normalizedSource, normalizedTarget,
StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES);
}StandardCopyOption — это enum (перечисление), тип данных в Java, представляющий фиксированный набор констант. REPLACE_EXISTING разрешает перезапись существующего файла, COPY_ATTRIBUTES копирует метаданные (права доступа, временные метки).Пример 4: Работа с временными файлами
public Path createTempFileWithPath() throws IOException {
// getDefault() возвращает файловую систему по умолчанию
Path tempDir = FileSystems.getDefault().getPath(System.getProperty("java.io.tmpdir"));
// createTempFile создаёт файл с префиксом и суффиксом
Path tempFile = Files.createTempFile(tempDir, "app_", ".tmp");
System.out.println("Created: " + tempFile.toAbsolutePath());
return tempFile;
}System.getProperty("java.io.tmpdir") возвращает путь к временной директории ОС. Files.createTempFile гарантирует уникальность имени через атомарную операцию на уровне файловой системы.Path vs File: ключевые различия
Класс java.io.File (существует с Java 1.0) имеет ряд архитектурных недостатков:
Смешение ответственности:
File одновременно представляет и путь, и файл, и директорию. Path разделяет эти концепции.Ограниченная поддержка символических ссылок:
File не различает символическую ссылку и целевой файл. Path в сочетании с Files предоставляет полный контроль.Отсутствие нормализации:
File не предоставляет методов для работы с . и ... Path.normalize() решает это.Нет поддержки файловых систем, отличных от дефолтной:
Path работает с любой FileSystem — ZIP, память, сетевые ФС.Методы
File возвращают boolean вместо исключений: file.delete() возвращает false при ошибке, не объясняя причину. Files.delete(path) выбрасывает IOException с деталями.#Java #для_новичков #beginner #IO #NIO #Path
👍5
Что выведет код?
#Tasks
import java.nio.file.Path;
import java.nio.file.Paths;
public class Task070726 {
public static void main(String[] args) {
Path p1 = Paths.get("/foo");
Path p2 = Paths.get("/bar");
Path p3 = p1.resolve(p2);
Path p4 = p1.resolve("bar");
System.out.print(p3 + " " + p4);
}
}
#Tasks
👍3
Варианты ответа:
Anonymous Quiz
22%
/foo/bar /bar
11%
/bar /foo/bar
44%
/foo/bar /foo/bar
22%
/bar /bar
👍3