Java for Beginner
677 subscribers
546 photos
155 videos
12 files
836 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Вызов методов через Reflection

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

1. Использование Method.invoke() для вызова методов

Метод Method.invoke() позволяет вызывать методы объекта динамически. Вы можете получить объект Method с помощью getDeclaredMethod() или getMethod(), а затем вызвать его.

Как это работает:
Вы получаете объект Class.
С помощью getDeclaredMethod() или getMethod() получаете объект Method.
Вызываете метод invoke(), передавая объект и аргументы.


Пример кода:
public class MyClass {
public void sayHello(String name) {
System.out.println("Привет, " + name + "!");
}
}

public class ReflectionExample {
public static void main(String[] args) {
try {
// Получаем объект Class
Class<?> clazz = Class.forName("MyClass");

// Создаем объект
Object obj = clazz.getDeclaredConstructor().newInstance();

// Получаем метод sayHello с параметром String
Method method = clazz.getDeclaredMethod("sayHello", String.class);

// Вызываем метод
method.invoke(obj, "John");
} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException |
IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}


Плюсы:
Позволяет вызывать методы динамически.
Поддерживает методы с параметрами.


Минусы:
Медленнее, чем прямой вызов метода.
Может выбросить исключения, если метод недоступен или параметры не совпадают.


Под капотом:
Метод invoke() использует нативные вызовы для выполнения метода. Это требует дополнительных проверок и может привести к снижению производительности.

2. Обработка исключений при вызове методов

При работе с Reflection важно правильно обрабатывать исключения.

Основные исключения, которые могут возникнуть:
IllegalAccessException: если метод недоступен (например, он private).
InvocationTargetException: если метод выбросил исключение.
NoSuchMethodException: если метод не найден.


Пример обработки исключений:
try {
Method method = clazz.getDeclaredMethod("sayHello", String.class);
method.setAccessible(true); // Разрешаем доступ к private методам
method.invoke(obj, "John");
} catch (NoSuchMethodException e) {
System.out.println("Метод не найден: " + e.getMessage());
} catch (IllegalAccessException e) {
System.out.println("Нет доступа к методу: " + e.getMessage());
} catch (InvocationTargetException e) {
System.out.println("Метод выбросил исключение: " + e.getCause().getMessage());
}


Плюсы:
Позволяет безопасно работать с Reflection.
Помогает отлаживать проблемы.


Минусы:
Увеличивает объем кода.
Требует внимательности при обработке исключений.


#Java #Training #Medium #Reflection_API #Method_invoke
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Введение в модульность и история Java Platform Module System — JPMS

Модульность — это принцип проектирования программного обеспечения, при котором система разбивается на отдельные, независимые компоненты (модули). Каждый модуль инкапсулирует определенную функциональность и взаимодействует с другими модулями через четко определенные интерфейсы.

Зачем нужна модульность?


Управление зависимостями: Модульность позволяет явно указывать, какие модули зависят от других, что упрощает управление зависимостями и предотвращает конфликты.
Изоляция кода: Модули изолируют код, что уменьшает вероятность непреднамеренного взаимодействия между частями системы.
Улучшение производительности: Модульность позволяет загружать только те части приложения, которые действительно нужны, что может улучшить производительность и уменьшить использование памяти.


Проблемы, которые решает модульность

До появления модульности в Java разработчики сталкивались с несколькими проблемами:
JAR Hell: Конфликты версий библиотек из-за отсутствия четкого управления зависимостями.
Отсутствие инкапсуляции: Все классы в classpath были доступны друг другу, что могло привести к непреднамеренному использованию внутренних API.
Большие размеры приложений: Приложения включали все библиотеки, даже если они не использовались, что увеличивало размер и время запуска.


История появления JPMS (Java Platform Module System)

Java Platform Module System (JPMS), также известный как Project Jigsaw, был введен в Java 9 для решения вышеупомянутых проблем.

JPMS добавил в Java поддержку модульности на уровне языка, что позволило:
Разделять JDK на модули, что уменьшило размер runtime-окружения.
Управлять зависимостями на уровне модулей.
Улучшить безопасность и производительность за счет инкапсуляции.


Основные концепции

Модуль (module) как единица инкапсуляции
Модуль в Java — это набор пакетов, который может быть скомпилирован и запущен независимо. Модуль определяет, какие пакеты он экспортирует (делает доступными для других модулей) и какие модули ему необходимы для работы.
Файл
module-info.java — его структура и назначение
Каждый модуль должен содержать файл
module-info.java, который описывает его структуру и зависимости. Этот файл находится в корне модуля и содержит директивы, определяющие, какие пакеты экспортируются, какие модули требуются и т.д.

Пример простого модуля:
module com.example.myapp {
requires java.base; // Зависимость от базового модуля Java
exports com.example.myapp.api; // Экспорт пакета com.example.myapp.api
}
В этом примере модуль com.example.myapp зависит от базового модуля java.base и экспортирует пакет com.example.myapp.api.


#Java #Training #Medium #JPMS
Что выведет код?

import java.util.function.Function;

public class Task120225 {
public static void main(String[] args) {
Function<String, String> func1 = String::toUpperCase;
Function<String, String> func2 = s -> s.toUpperCase();

String result1 = func1.apply("hello");
String result2 = func2.apply("hello");

System.out.println(result1 == result2);
}
}


#Tasks
У нее деплой на носу, а тут какой-то газоанализатор 🤪 😅

https://t.me/Java_for_beginner_dev

#Mems
Please open Telegram to view this post
VIEW IN TELEGRAM
Вопросы с собеседования 👩‍💻

Какой метод используется для сравнения строк в Java?
Anonymous Quiz
10%
==
77%
equals()
8%
compareTo()
4%
equalsIgnoreCase()
Ключевые директивы JPMS

requires — для указания зависимостей

Директива requires используется для указания зависимостей модуля. Она указывает, что текущий модуль зависит от другого модуля.

Пример:
module com.example.myapp {
requires java.sql; // Зависимость от модуля java.sql
}


exports — для экспорта пакетов

Директива exports делает пакет доступным для других модулей. Только экспортированные пакеты могут быть использованы вне модуля.

Пример:
module com.example.myapp {
exports com.example.myapp.api; // Экспорт пакета com.example.myapp.api
}


opens — для открытия пакетов к рефлексии

Директива opens позволяет другим модулям использовать рефлексию для доступа к пакетам. Это полезно для фреймворков, таких как Hibernate или Spring, которые используют рефлексию для работы с классами.

Пример:
module com.example.myapp {
opens com.example.myapp.internal; // Открытие пакета com.example.myapp.internal для рефлексии
}


provides и uses — для работы с сервисами

Директивы provides и uses используются для работы с сервисами в модульной системе. provides указывает, что модуль предоставляет реализацию определенного сервиса, а uses указывает, что модуль использует сервис.

Пример:
module com.example.myapp {
provides com.example.myapp.spi.MyService with com.example.myapp.MyServiceImpl; // Предоставление реализации сервиса
uses com.example.myapp.spi.MyService; // Использование сервиса
}


Создание и использование модулей

Давайте рассмотрим пример создания и использования модулей в Java. Предположим, у нас есть два модуля: com.example.myapp и com.example.mylib.

Модуль com.example.mylib

Этот модуль предоставляет библиотеку для работы с математическими операциями.
// module-info.java для com.example.mylib
module com.example.mylib {
exports com.example.mylib.math; // Экспорт пакета com.example.mylib.math
}


// com/example/mylib/math/MathUtils.java
package com.example.mylib.math;

public class MathUtils {
public static int add(int a, int b) {
return a + b;
}
}


Модуль com.example.myapp

Этот модуль использует библиотеку com.example.mylib для выполнения математических операций.

// module-info.java для com.example.myapp
module com.example.myapp {
requires com.example.mylib; // Зависимость от модуля com.example.mylib
}


// com/example/myapp/Main.java
package com.example.myapp;

import com.example.mylib.math.MathUtils;

public class Main {
public static void main(String[] args) {
int result = MathUtils.add(5, 3);
System.out.println("Result: " + result);
}
}


Плюсы и минусы модульности

Плюсы:

Улучшенное управление зависимостями: Модульность позволяет явно указывать зависимости, что упрощает управление ими и предотвращает конфликты.
Инкапсуляция: Модули скрывают внутренние детали реализации, что делает код более безопасным и устойчивым к изменениям.
Улучшенная производительность: Загрузка только необходимых модулей может уменьшить время запуска и использование памяти.


Минусы:
Сложность: Модульность добавляет дополнительный уровень сложности в разработку и сборку приложений.
Ограниченная совместимость: Некоторые старые библиотеки и фреймворки могут не поддерживать модульность, что может вызвать проблемы при миграции.


Нюансы использования

Рефлексия: Если вы используете рефлексию для доступа к классам, убедитесь, что соответствующие пакеты открыты с помощью директивы opens.
Миграция: При переходе на модульную систему может потребоваться переработка существующего кода и зависимостей.
Сборка: Использование модульности может потребовать изменений в процессе сборки и развертывания приложений.


#Java #Training #Medium #JPMS
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Модульность и Maven

1. Настройка многомодульного проекта в Maven

Многомодульный проект в Maven — это проект, который состоит из нескольких подпроектов (модулей), каждый из которых может быть собран и использован независимо. Основная идея — разделение функциональности на логические модули, что упрощает управление кодом и зависимостями.

Структура многомодульного проекта:
parent-project/
├── pom.xml
├── module1/
│ └── pom.xml
├── module2/
│ └── pom.xml
└── module3/
└── pom.xml


parent-project/pom.xml — корневой POM-файл, который объединяет все модули.
module1/, module2/, module3/ — отдельные модули, каждый со своим POM-файлом.


Пример корневого pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging> <!-- Указываем, что это родительский POM -->

<modules>
<module>module1</module>
<module>module2</module>
<module>module3</module>
</modules>
</project>


Пример pom.xml для модуля (module1):
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>module1</artifactId>
</project>


2. Управление зависимостями между модулями

Чтобы один модуль мог использовать другой, нужно добавить зависимость в pom.xml.

Например, если module2 зависит от module1, то в pom.xml module2 нужно добавить:
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>module1</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>


Плюсы:
Четкое разделение ответственности между модулями.
Упрощение управления зависимостями.
Возможность повторного использования кода.


Минусы:
Усложнение структуры проекта.
Необходимость тщательного планирования зависимостей.


#Java #Training #Medium #JPMS #Maven
3. Пример конфигурации pom.xml для модульного проекта

Рассмотрим пример, где module1 содержит общие утилиты, module2 — бизнес-логику, а module3 — веб-интерфейс.

Корневой pom.xml:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>

<modules>
<module>module1</module>
<module>module2</module>
<module>module3</module>
</modules>
</project>


pom.xml для module1:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>module1</artifactId>
</project>


pom.xml для module2:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>module2</artifactId>

<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>module1</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

pom.xml для module3:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>module3</artifactId>

<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>module2</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>


Сборка и запуск модульных проектов

1. Сборка модульного проекта с помощью Maven

Maven:
mvn clean install


2. Запуск модульного приложения

Для запуска приложения, собранного с помощью Maven, используйте команду java -jar, указав путь к JAR-файлу.

#Java #Training #Medium #JPMS #Maven
Что выведет код?

import java.util.stream.IntStream;

public class Task130225 {
public static void main(String[] args) {
int sum = IntStream.range(1, 5)
.filter(i -> i % 2 == 0)
.map(i -> i * 2)
.sum();
System.out.println(sum);
}
}


#Tasks
Варианты ответа:
Anonymous Quiz
13%
6
68%
12
8%
20
11%
Exception
🧐 да там на всех эндпоинтах такая валидация что фиг пробьешься 🤓

https://t.me/Java_for_beginner_dev

#Mems
Please open Telegram to view this post
VIEW IN TELEGRAM
Вопросы с собеседования 👩‍💻

Какой интерфейс используется для сортировки элементов в коллекции?
Anonymous Quiz
27%
List
17%
Set
52%
Comparable
4%
Map
Модульность и Gradle

1. Настройка многомодульного проекта в Gradle

Gradle использует декларативный подход для настройки проектов. В отличие от Maven, где конфигурация задается в XML, Gradle использует Groovy или Kotlin DSL, что делает его более гибким и мощным.

Структура многомодульного проекта:
parent-project/
├── build.gradle
├── settings.gradle
├── module1/
│ └── build.gradle
├── module2/
│ └── build.gradle
└── module3/
└── build.gradle


settings.gradle — определяет, какие модули входят в проект.
build.gradle — корневой файл сборки, который может содержать общие настройки для всех модулей.


Пример settings.gradle:
rootProject.name = 'parent-project'
include 'module1', 'module2', 'module3'


Пример корневого build.gradle:
allprojects {
group = 'com.example'
version = '1.0-SNAPSHOT'
}

subprojects {
apply plugin: 'java'
repositories {
mavenCentral()
}
}


Пример build.gradle для модуля (module1):
dependencies {
// Зависимости модуля
}


2. Управление зависимостями между модулями

В Gradle зависимости между модулями добавляются с помощью ключевого слова project.

Например, если module2 зависит от module1, то в build.gradle module2 нужно добавить:
dependencies {
implementation project(':module1')
}


Плюсы:
Гибкость и мощь Groovy/Kotlin DSL.
Быстрая сборка благодаря инкрементальной компиляции.
Поддержка современных практик, таких как контейнеризация.


Минусы:
Более сложная настройка по сравнению с Maven.
Требует знания Groovy/Kotlin.


3. Пример конфигурации build.gradle для модульного проекта

Корневой build.gradle:
allprojects {
group = 'com.example'
version = '1.0-SNAPSHOT'
}

subprojects {
apply plugin: 'java'
repositories {
mavenCentral()
}
}


build.gradle для module1:
dependencies {
// Зависимости модуля
}


build.gradle для module2:
dependencies {
implementation project(':module1')
}


build.gradle для module3:
dependencies {
implementation project(':module2')
}


Сборка и запуск модульных проектов

1. Сборка модульного проекта с помощью Gradle

Gradle:
gradle build


2. Запуск модульного приложения
Для запуска приложения, собранного с помощью Gradle, используйте команду java -jar, указав путь к JAR-файлу.

Пример:
java -jar module3/build/libs/module3-1.0-SNAPSHOT.jar


3. Использование jlink для создания минимальных runtime-образов

jlink — это утилита, которая позволяет создавать минимальные runtime-образы Java, включающие только необходимые модули. Это полезно для уменьшения размера приложения.

Пример использования:
jlink --module-path $JAVA_HOME/jmods:mods --add-modules com.example.module1 --output myapp-runtime


Плюсы:
Уменьшение размера приложения.
Ускорение запуска приложения.
Упрощение развертывания.


Минусы:
Требует знания модульной системы Java.
Необходимость тщательного планирования зависимостей.
Пример полного цикла: от сборки до запуска


Сборка проекта:
gradle build


Создание runtime-образа:
jlink --module-path $JAVA_HOME/jmods:mods --add-modules com.example.module1 --output myapp-runtime


Запуск приложения:
./myapp-runtime/bin/java -m com.example.module1/com.example.module1.Main


#Java #Training #Medium #JPMS #Gradle #Jlink
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM