uk
Feedback
Java | Фишки и трюки

Java | Фишки и трюки

Відкрити в Telegram

Java: примеры кода, интересные фишки и полезные трюки Купить рекламу: https://telega.in/c/java_tips_and_tricks ✍️По всем вопросам: @Pascal4eg Менеджер по рекламе: @shmyzna

Показати більше
6 953
Підписники
-324 години
-27 днів
+630 день
Архів дописів
412.103.213 рублей – столько россияне потратили на материалы по айти в 2024 году А могли просто скачать 213 ГБ бесплатных гай
412.103.213 рублей – столько россияне потратили на материалы по айти в 2024 году А могли просто скачать 213 ГБ бесплатных гайдов по программированию, с которыми можно подтянуть свои скиллы и выучить новые ЯП: Гайды по JavaScript Гайды по Java Гайды по C# Гайды по PHP Гайды по C++ Гайды по TypeScript Гайды по Go Гайды по Swift Гайды по Kotlin Гайды по Ruby Гайды по Rust Гайды по Scala Гайды по Perl Гайды по R Аналогов этому ресурсу больше нет, не благодарите.

⌨️ Приведение типов. Понижение и повышение типа Java является строго типизированным языком программирования, а это означает, то что каждое выражение и каждая переменная имеет строго определенный тип уже на момент компиляции. Однако определен механизм приведения типов (casting) - способ преобразования значения переменной одного типа в значение другого типа. В Java существуют несколько разновидностей приведения: ✔️ Тождественное (identity). Преобразование выражения любого типа к точно такому же типу всегда допустимо и происходит автоматически. ✔️ Расширение (повышение, upcasting) примитивного типа (widening primitive). Означает, что осуществляется переход от менее емкого типа к более ёмкому. Например, от типа byte (длина 1 байт) к типу int (длина 4 байта). Такие преобразование безопасны в том смысле, что новый тип всегда гарантировано вмещает в себя все данные, которые хранились в старом типе и таким образом не происходит потери данных. Этот тип приведения всегда допустим и происходит автоматически. ✔️ Сужение (понижение, downcasting) примитивного типа (narrowing primitive). Означает, что переход осуществляется от более емкого типа к менее емкому. При таком преобразовании есть риск потерять данные. Например, если число типа int было больше 127, то при приведении его к byte значения битов старше восьмого будут потеряны. В Java такое преобразование должно совершаться явным образом, при этом все старшие биты, не умещающиеся в новом типе, просто отбрасываются - никакого округления или других действий для получения более корректного результата не производится. ✔️ Расширение объектного типа (widening reference). Означает неявное восходящее приведение типов или переход от более конкретного типа к менее конкретному, т.е. переход от потомка к предку. Разрешено всегда и происходит автоматически. ✔️ Сужение объектного типа (narrowing reference). Означает нисходящее приведение, то есть приведение от предка к потомку (подтипу). Возможно только если исходная переменная является подтипом приводимого типа. При несоответствии типов в момент выполнения выбрасывается исключение ClassCastException. Требует явного указания типа. ✔️ Преобразование к строке (to String). Любой тип может быть приведен к строке, т.е. к экземпляру класса String. ✔️ Запрещенные преобразования (forbidden). Не все приведения между произвольными типами допустимы. Например, к запрещенным преобразованиям относятся приведения от любого ссылочного типа к примитивному и наоборот (кроме преобразования к строке). Кроме того, невозможно привести друг к другу классы, находящиеся на разных ветвях дерева наследования и т.п. При приведении ссылочных типов с самим объектом ничего не происходит, - меняется лишь тип ссылки, через которую происходит обращение к объекту. Для проверки возможности приведения нужно воспользоваться оператором instanceof:

Parent parent = new Child();
if (parent instanceof Child) {
    Child child = (Child) parent;
}
#java #casting #upcasting #downcasting

🟡 Retrofit это библиотека для работы с REST API, которая значительно упрощает процесс выполнения HTTP-запросов в Android-приложениях. Она позволяет разработчикам сосредоточиться на логике приложения, избавляя от необходимости вручную обрабатывать сетевые запросы. Retrofit поддерживает методы HTTP (GET, POST, PUT, DELETE) и интеграцию с другими библиотеками, такими как Gson для обработки JSON-данных. 🔵Для начала работы с Retrofit необходимо добавить зависимости в файл build.gradle вашего проекта:

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
✔️Эти зависимости обеспечивают работу Retrofit и конвертацию JSON-ответов в объекты Java. 🔵После добавления зависимостей нужно настроить экземпляр Retrofit. Это делается с помощью класса Retrofit.Builder, где указывается базовый URL API и конвертер для обработки данных:

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();
🔵Следующий шаг — создание интерфейса для описания методов API. Например:

public interface ApiService {
    @GET("users")
    Call<List<User>> getUsers();
}
✔️Метод @GET("users") указывает конечную точку API. 🔵Чтобы выполнить запрос, нужно создать экземпляр интерфейса через объект Retrofit:

ApiService apiService = retrofit.create(ApiService.class);
apiService.getUsers().enqueue(new Callback>() {
    @Override
    public void onResponse(Call<List<User>> call, Response<List<User>> response) {
        if (response.isSuccessful()) {
            List<User> users = response.body();
            // Обработка данных
        } else {
            // Обработка ошибки
        }
    }

    @Override
    public void onFailure(Call<List<User>> call, Throwable t) {
        // Обработка ошибки сети
    }
});
🔵Этот код выполняет асинхронный запрос к серверу. Если запрос успешен, данные из ответа преобразуются в список объектов User. ✔️Пример класса модели данных:

public class User {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}
🔵Retrofit также поддерживает передачу параметров в запросы. Например, для получения данных о конкретном пользователе можно использовать аннотацию @Path:

public interface ApiService {
    @GET("users/{id}")
    Call<User> getUser(@Path("id") int userId);
}
🔵Вызов метода будет выглядеть так:

apiService.getUser(1).enqueue(new Callback() {
    @Override
    public void onResponse(Call<User> call, Response response) {
        if (response.isSuccessful()) {
            User user = response.body();
            // Обработка данных пользователя
        }
    }

    @Override
    public void onFailure(Call<User> call, Throwable t) {
        // Обработка ошибки сети
    }
});
🔵Retrofit позволяет легко работать с заголовками HTTP через аннотацию @Header:

public interface ApiService {
    @GET("users")
    Call<List<User>> getUsers(@Header("Authorization") String token);
}
🔵Библиотека также поддерживает обработку сложных сценариев взаимодействия с сервером, таких как отправка тела запроса (@Body) или параметров запроса (@Query). Например:

public interface ApiService {
    @POST("users")
    Call<User> createUser(@Body User user);

    @GET("users")
    Call<List<User>> getUsers(@Query("page") int page);
}
💠Retrofit значительно упрощает работу с сетью в Android-приложениях (и не только). Он делает код более чистым и поддерживаемым, а также позволяет легко интегрировать другие инструменты для обработки данных.

💠Gson — это библиотека от Google, предназначенная для работы с JSON в Java-приложениях. Она позволяет легко преобразовывать объекты Java в JSON и обратно, избавляя разработчиков от необходимости писать шаблонный код для парсинга данных. Gson поддерживает сложные структуры данных, такие как коллекции, вложенные объекты и даже объекты без исходного кода. 🟣Почему стоит использовать Gson? 1.🧬 Простота интеграции: Для использования достаточно добавить зависимость в build.gradle:   

   implementation 'com.google.code.gson:gson:2.12.1'
   
2.🧬Мощные возможности сериализации и десериализации: Gson поддерживает преобразование объектов любой сложности. 3.🧬Интеграция с Retrofit: Gson часто используется в качестве конвертера для обработки данных из API. 4.🧬 Настраиваемость: С помощью GsonBuilder можно задать форматирование JSON, исключение полей и другие настройки. ⚡️Пример 1: Сериализация объекта. ➡️Сериализация — это процесс преобразования объекта Java в строку JSON. Рассмотрим простой пример:

public class User {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
➡️Создадим объект User и преобразуем его в JSON:

Gson gson = new Gson();
User user = new User("John", 25);
String json = gson.toJson(user);
System.out.println(json);
➡️Результат:

{"name":"John","age":25}
⚡️Пример 2: Десериализация JSON ➡️Десериализация — это обратный процесс, преобразующий строку JSON в объект Java:

String json = "{\"name\":\"Jane\",\"age\":30}";
User user = gson.fromJson(json, User.class);
System.out.println("Имя: " + user.getName() + ", Возраст: " + user.getAge());
➡️Результат: Имя: Jane, Возраст: 30 ⚡️Пример 3: Работа с коллекциями ➡️Если данные представлены в виде массива JSON, Gson может преобразовать их в список объектов:

String jsonArray = "[{\"name\":\"John\",\"age\":25},{\"name\":\"Jane\",\"age\":30}]";
Type userListType = new TypeToken<List<User>>() {}.getType();
List<User> users = gson.fromJson(jsonArray, userListType);

for (User user : users) {
    System.out.println("Имя: " + user.getName() + ", Возраст: " + user.getAge());
}
➡️Результат: Имя: John, Возраст: 25  Имя: Jane, Возраст: 30 ⚡️Пример 4: Настройка через GsonBuilder. ➡️С помощью GsonBuilder можно настроить форматирование JSON или исключение определённых полей:

Gson gson = new GsonBuilder()
    .setPrettyPrinting()
    .excludeFieldsWithoutExposeAnnotation()
    .create();
String json = gson.toJson(user);
System.out.println(json);
➡️Результат будет отформатирован для удобного чтения:

{
  "name": "John",
  "age": 25
}
💎Обработка ошибок при десериализации ➡️Если формат JSON некорректен или не соответствует ожидаемому, может возникнуть ошибка JsonSyntaxException. Чтобы избежать краша приложения, используйте блок try-catch:

try {
    User user = gson.fromJson("{invalid_json}", User.class);
} catch (JsonSyntaxException e) {
    e.printStackTrace();
}

🔍Тестовое собеседование на Middle Java-разработчика завтра 9 апреля(уже завтра!) в 19:00 по мск приходи онлайн на открытое с
🔍Тестовое собеседование на Middle Java-разработчика завтра 9 апреля(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика. Как это будет: 📂 Илья Аров, старший разработчик в Т1, будет задавать реальные вопросы и задачи разработчику-добровольцу 📂 Илья будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью 📂 В конце можно будет задать любой вопрос Илье Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы. Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqvXt7qT

💎Enum как полноценные классы с методами и интерфейсами Enum в Java — это не просто перечисление констант. Это полноценные классы с конструкторами, методами и поддержкой ООП. 💠 1. Enum с абстрактными методами

public enum FileFormat {
    CSV {
        public String parse(String data) {
            return data.replace(",", ";");
        }
    },
    JSON {
        public String parse(String data) {
            return "{" + data + "}";
        }
    };
    
    public abstract String parse(String data);
}
💠 2. Реализация интерфейсов 

public interface Formatter {
    String format(String text);
}

public enum TextFormat implements Formatter {
    UPPERCASE {
        public String format(String text) {
            return text.toUpperCase();
        }
    },
    LOWERCASE {
        public String format(String text) {
            return text.toLowerCase();
        }
    };
}

// Пример вызова
String result = TextFormat.UPPERCASE.format("Hello"); // "HELLO"
💠 3. Состояния и полиморфизм 

public enum OrderStatus {
    NEW(1) {
        public OrderStatus next() {
            return PROCESSING;
        }
    },
    PROCESSING(2) {
        public OrderStatus next() {
            return SHIPPED;
        }
    },
    SHIPPED(3) {
        public OrderStatus next() {
            return COMPLETED;
        }
    };

    private final int code;

    OrderStatus(int code) {
        this.code = code;
    }

    public abstract OrderStatus next();
}
💠 4. Enum в JPA-сущностях 

@Entity
public class Order {
    @Enumerated(EnumType.STRING)
    private OrderStatus status;
}

// Сохраняется как строка "NEW", "PROCESSING" в БД
💠 5. Поиск по значению 

public static OrderStatus findByCode(int code) {
    return Arrays.stream(OrderStatus.values())
        .filter(status -> status.code == code)
        .findFirst()
        .orElseThrow();
}
⚠️ Опасности:  ▸ Перегруженность логикой нарушает принцип SRP  ▸ Сложность тестирования из-за статической природы  ▸ Ограниченная расширяемость после компиляции  Практические кейсы:  ▸ Фабрики объектов с предопределёнными настройками  ▸ State Machine для управления состоянием приложения  ▸ Конфигурация параметров системы  💠Пример интеграции с Stream API

public enum MathOperation {
    PLUS("+", (a, b) -> a + b),
    MINUS("-", (a, b) -> a - b);

    private final String symbol;
    private final IntBinaryOperator operation;

    MathOperation(String symbol, IntBinaryOperator operation) {
        this.symbol = symbol;
        this.operation = operation;
    }

    public int apply(int a, int b) {
        return operation.applyAsInt(a, b);
    }
}

// Использование
int result = MathOperation.PLUS.apply(5, 3); // 8
💠P.S. enum в switch-выражениях

String description = switch (status) {
    case NEW -> "Новый заказ";
    case PROCESSING -> "В обработке";
    case SHIPPED -> "Отправлен";
};
💠Дополнение:  Используйте EnumSet для эффективной работы с группами констант: 

EnumSet activeStatuses = EnumSet.of(NEW, PROCESSING);
if (activeStatuses.contains(currentStatus)) {
    // Логика для активных статусов
}

Ищем Java специалистов. Релокейт, удалёнка, платим много! Специально для Вас, собираем лучшие вакансии с прямыми контактами в
Ищем Java специалистов. Релокейт, удалёнка, платим много! Специально для Вас, собираем лучшие вакансии с прямыми контактами в Telegram на канале @it_match_java. Подпишись чтобы не упустить свой шанс получить лучший оффер!

🖥 Блоки инициализации в Java Блоки инициализации позволяют гибко управлять созданием объектов. Вот как их правильно использовать: 💠 Нестатические блоки Выполняются перед конструктором:
public class Logger {
    private String prefix;
    
    { // Блок инициализации экземпляра (выполняется перед конструктором)
        prefix = "[LOG] " + LocalDateTime.now();  // Инициализация префикса с текущей датой/временем
        System.out.println("Логгер готов!");      // Сообщение о готовности логгера
    }
    
    public Logger() {
        System.out.println(prefix + " | Новый объект");  // Вывод информации о создании объекта
    }
}
Для чего: предварительная настройка полей, валидация, логирование. 💠 Статические блоки Срабатывают один раз при загрузке класса:
public class ConfigLoader {
    static {
        System.out.println("Загружаем конфиги...");
        // Здесь можно читать файлы, подключать БД и т.д.
    }
}
Для чего: инициализация кэшей, регистрация драйверов, загрузка ресурсов. 📝 Когда что использовать - Нестатические блоки → простая инициализация полей - Статические блоки → настройка системных ресурсов 🧬Дополнение: Для улучшения читаемости кода используйте блоки инициализации для простых операций. Избегайте сложной логики — это может затруднить отладку и понимание приложения.

⚡️ ИИ захватывает рынок. А ты всё ещё смотришь туториалы по Python? Пока ты открываешь 10-й гайд по Django, другие уже развор
⚡️ ИИ захватывает рынок. А ты всё ещё смотришь туториалы по Python? Пока ты открываешь 10-й гайд по Django, другие уже разворачивают модели в проде и оптимизируют пайплайны на Spark. ⚠️ Спойлер: они не умнее тебя. Просто выбрали правильные источники. 😍 Архив Программиста — твой фундамент: языки, фреймворки, база. 💙 Data Signal — следующий уровень: Data Science, ML, Big Data. Вместе — это полный стек навыков, чтобы оставаться в игре. Подписывайся на оба — и стань тем, кого не догонят.

⌨️ Что такое Project Jigsaw? До Java 9 весь Java-код (и твой, и JDK) хранился в виде «монолитных» JAR-файлов, и зависимости между ними не контролировались явно. Project Jigsaw решил эту проблему, введя модули, которые: Четко определяют, что экспортируется наружу. Указывают, от чего зависят. Позволяют уменьшить размер приложения (особенно полезно для Java SE Embedded). Улучшают безопасность и инкапсуляцию. Каждый модуль содержит файл module-info.java, в котором описываются зависимости и экспортируемые пакеты. ➡️ Пример module-info.java:

module com.example.app {
    requires java.sql;
    exports com.example.app.api;
}
Преимущества модульной системы: Четкая структура зависимостей. Улучшенная читаемость и поддерживаемость. Компиляция и запуск только нужных модулей. Инкапсуляция внутренних пакетов (по умолчанию они недоступны извне).

⌨️ Автоупаковка (autoboxing). Правила упаковки примитивных типов в классы-обертки Автоупаковка - это механизм неявной инициализации объектов классов-оберток (Byte, Short, Integer, Long, Float, Double, Character, Boolean) значениями соответствующих им исходных примитивных типов (byte, short, int...), без явного использования конструктора класса. Автоупаковка происходит при прямом присваивании примитива классу-обертке (с помощью оператора =), либо при передаче примитива в параметры метода (типа класса-обертки). Автоупаковке в классы-обертки могут быть подвергнуты как переменные примитивных типов, так и константы времени компиляции (литералы и final-примитивы). При этом литералы должны быть синтаксически корректными для инициализации переменной исходного примитивного типа. Автоупаковка переменных примитивных типов требует точного соответствия типа исходного примитива типу класса-обертки. Например, попытка упаковать переменную типа byte в Short, без предварительного явного приведения byte в short вызовет ошибку компиляции. Автоупаковка констант примитивных типов допускает более широкие границы соответствия. В этом случае компилятор способен предварительно осуществлять неявное расширение/сужение типа примитивов: ✔️ неявное расширение/сужение исходного типа примитива до типа примитива, соответствующего классу-обертке (для преобразования int в Byte, сначала компилятор самостоятельно неявно сужает int к byte) ✔️ автоупаковку примитива в соответствующий класс-обертку. Однако, в этом случае существуют два дополнительных ограничения: a) присвоение примитива обертке может производится только оператором = (нельзя передать такой примитив в параметры метода без явного приведения типов) b) тип левого операнда не должен быть старше чем Character, тип правого не должен старше, чем int: допустимо расширение/сужение byte в/из short, byte в/из char, short в/из char и только сужение byte из int, short из int, char из int. Все остальные варианты требуют явного приведения типов). Дополнительной особенностью целочисленных классов-оберток, созданных автоупаковкой констант в диапазоне -128 ... +127 является то, что они кэшируются JVM. Поэтому такие обертки с одинаковыми значениями будут являться ссылками на один объект. #java #autoboxing

ИИ-помощника в каждый бизнес! ✨Акция на Битрикс24 Купи годовой тариф Битрикс24 со скидкой - 30% и получи ИИ-помощника на сумм
ИИ-помощника в каждый бизнес! ✨Акция на Битрикс24 Купи годовой тариф Битрикс24 со скидкой - 30% и получи ИИ-помощника на сумму 100 000 рублей бонусом. Делаем искусственный интеллект доступным каждому бизнесу.❤️ Узнать больше #реклама 16+ ai-sale.bitrix24.ru О рекламодателе

⌨️ Лямбда-выражения и свой кастомный функциональный интерфейс Для того что бы определить лямбда-выражение, нам нужен функциональный интерфейс. Изобретём свой:

@FunctionalInterface
interface MathOperation {
    int operate(int a, int b);
}
Функциональный интерфейс MathOperation содержит один абстрактный метод operate, который принимает два значения типа int и возвращает int. Аннотация @FunctionalInterface указывает на то, что интерфейс предназначен для использования в функциональном программировании и должен содержать только один абстрактный метод. Но аннотация не обязательна. Использование лямбда-выражения:

public class LambdaExample {
    public static void main(String[] args) {
        // Реализация интерфейса с помощью лямбда-выражения
        MathOperation addition = (a, b) -> a + b;
        MathOperation subtraction = (a, b) -> a - b;
        MathOperation multiplication = (a, b) -> a * b;
        MathOperation division = (a, b) -> a / b;

        int x = 10;
        int y = 5;

        System.out.println("Addition: " + operate(x, y, addition)); // 15
        System.out.println("Subtraction: " + operate(x, y, subtraction)); // 5
        System.out.println("Multiplication: " + operate(x, y, multiplication)); // 50
        System.out.println("Division: " + operate(x, y, division)); // 2
    }

    // Метод, принимающий MathOperation и применяющий его к данным
    private static int operate(int a, int b, MathOperation operation) {
        return operation.operate(a, b);
    }
}
В нашем примере лямбда-выражения используются для создания экземпляров интерфейса MathOperation для выполнения различных математических операций (сложение, вычитание и т.д.). Метод operate принимает два целых числа и функциональный интерфейс MathOperation, затем выполняет переданную операцию. В метод в третьем параметре можно передать непосредственно лямбда-выражение, не используя промежуточную переменную. #java #lambda #FunctionalInterface

Я пожалею об этом, но ладно... В общем сливаю вам самый топовый источник сервисов, софта, программ, новостей из мира IT. Если после этого не сможешь обезопасить свой девайс, то ты безнадежен! Вот ссылка - https://t.me/+zxnnnF0q_wtmZTgy

☕️ JBCrypt 🔺JBCrypt - это библиотека для безопасного хеширования паролей в Java, реализующая алгоритм bcrypt. Она обеспечивает надежную защиту паролей от атак перебором и радужных таблиц. 💫 Пример: Система регистрации и аутентификации

import org.mindrot.jbcrypt.BCrypt;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class AuthenticationSystem {
    private static Map users = new HashMap<>();

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.println("1. Регистрация");
            System.out.println("2. Вход");
            System.out.println("3. Выход");
            System.out.print("Выберите действие: ");

            int choice = scanner.nextInt();
            scanner.nextLine(); // Очистка буфера

            switch (choice) {
                case 1:
                    register(scanner);
                    break;
                case 2:
                    login(scanner);
                    break;
                case 3:
                    System.out.println("До свидания!");
                    return;
                default:
                    System.out.println("Неверный выбор. Попробуйте снова.");
            }
        }
    }

    private static void register(Scanner scanner) {
        System.out.print("Введите имя пользователя: ");
        String username = scanner.nextLine();
        System.out.print("Введите пароль: ");
        String password = scanner.nextLine();

        String hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
        users.put(username, hashedPassword);

        System.out.println("Регистрация успешна!");
    }

    private static void login(Scanner scanner) {
        System.out.print("Введите имя пользователя: ");
        String username = scanner.nextLine();
        System.out.print("Введите пароль: ");
        String password = scanner.nextLine();

        if (users.containsKey(username) && BCrypt.checkpw(password, users.get(username))) {
            System.out.println("Вход выполнен успешно!");
        } else {
            System.out.println("Неверное имя пользователя или пароль.");
        }
    }
}
🛡JBCrypt предоставляет простой и эффективный способ защиты паролей пользователей. Использование этой библиотеки значительно повышает безопасность приложений, работающих с аутентификацией пользователей.

От чего зависит эффективность автотестов? От их правильного написания и поддерживаемости! В QA GURU мы учим приручать Java, чтобы ваши автотесты работали, как часы. Вот несколько лайфхаков, о которых мы расскажем на вводном занятии уже завтра (20:00 Мск): 1. Используйте понятные и описательные названия тестов Названия тестов должны четко отражать их цель. Это упрощает понимание кода всеми членами команды. Например: // Хорошо
public void verifyLoginWithValidCredentials() { ... }
// Плохо
public void test1() { ... }
Описательные названия помогают быстро понять, что проверяет тест, без необходимости изучения его внутренней логики. 2. Применяйте Page Object Model (POM) Page Object Model позволяет отделить логику теста от структуры веб-страницы, что делает код более модульным и удобным для поддержки при изменениях интерфейса. Пример использования: // Класс
Page Object
public class LoginPage {
    private By usernameField = By. id("username");
    private By passwordField = By. id("password");
    private By loginButton = By. id("loginBtn");

    public void enterUsername(String username) {
        driver.findElement(usernameField).sendKeys(username);
    }

    public void enterPassword(String password) {
        driver.findElement(passwordField).sendKeys(password);
    }

    public void clickLoginButton() {
        driver.findElement(loginButton).click();
    }
}
// Тестовый сценарий
LoginPage loginPage = new LoginPage(driver);
loginPage.enterUsername("john.doe");
loginPage.enterPassword("password123");
loginPage.clickLoginButton();
POM способствует повторному использованию кода и улучшает читаемость тестов. 3. Используйте параметризацию и data-driven подход Параметризованные тесты позволяют запускать один и тот же сценарий с различными входными данными, что увеличивает охват тестирования без дублирования кода.
@ ParameterizedTest
@ CsvSource({"john.doe, password123", "jane.smith, test@123"})
public void verifyLogin(String username, String password) {
    LoginPage loginPage = new LoginPage(driver);
    loginPage.enterUsername(username);
    loginPage.enterPassword(password);
    loginPage.clickLoginButton();
}
Этот подход делает тесты более гибкими и масштабируемыми. 4. Следуйте принципу AAA (Arrange, Act, Assert) Структурируйте тесты в три этапа: Arrange: подготовка данных и окружения. Act: выполнение действия. Assert: проверка результата. Пример:
@ Test
public void testAddition() {
    // Arrange
    Calculator calculator = new Calculator();

    // Act
    int result = calculator.add(2, 3);

    // Assert
    assertEquals(5, result);
}
Этот подход делает тесты более организованными и легко читаемыми. 5. Логирование и отчетность Добавляйте логирование в тесты для диагностики проблем:
log. info("Entering username: " + username);
log. info("Clicking on the login button");
Интеграция инструментов отчетности (например, Allure) помогает визуализировать результаты тестов и быстро выявлять ошибки. 6. Регулярные ревью кода Проводите регулярные ревью автотестов для повышения качества кода. Это помогает выявить потенциальные проблемы, улучшить читаемость и обеспечить соблюдение стандартов кодирования. 7. Автоматизация и CI/CD Используйте инструменты автоматизации (Maven, Gradle) для запуска тестов в рамках CI/CD пайплайнов. Это ускоряет процесс разработки и обеспечивает стабильность приложения на всех этапах. Хотите узнать больше? Присоединяйтесь завтра (20:00 Мск) к нашему бесплатному открытому уроку! 🔗 Зарегистрируйтесь на первый открытый урок по ссылке.

⌨️ Pattern Matching для instanceof Начиная с Java 16, проверка типов с помощью instanceof стала гораздо удобнее благодаря Pattern Matching. Раньше, после проверки объекта на принадлежность к определённому классу, нужно было выполнять явное приведение типа. Теперь это можно сделать в одной строке. Пример до Java 16:

if (obj instanceof String) {
    String str = (String) obj;
    System.out.println(str.length());
}
Пример с Pattern Matching:

if (obj instanceof String str) {
    System.out.println(str.length());
}
Теперь после instanceof можно сразу же использовать объект нужного типа в коде, что делает программу более читабельной и компактной. #java #PatternMatching #instanceof

Почему тебе стоит перейти на Go Для программистов, которые хотят работать над проектами уровня Kubernetes, а не "писать формы
Почему тебе стоит перейти на Go Для программистов, которые хотят работать над проектами уровня Kubernetes, а не "писать формы" Я напишу всего 5 причин, но их, на самом деле, больше. Простота и лаконичность кода Высокая производительность Отличная поддержка конкурентности Широкие возможности для backend-разработки Быстрая компиляция и кроссплатформенность И это далеко не всё. 2 апреля на вебинаре ты:  — Узнаешь, как переходить с других языков на Go, даже если ты уже прикипел к своему стеку.   — Получишь возможность всего за 2 месяца сменить свой стек и зарабатывать больше. Спикер вебинара - Дмитрий Березницкий. Chief Technical Officer с 20 летним опытом разработки решений в областях безопасности, блокчейна, финтеха и электронной коммерции, с основным фокусом на рынке США.  https://raise.kata.academy/web_go?utm_source=telegram&utm_medium=telegain&utm_campaign=web_go&utm_content=java_tips_and_tricks&erid=2W5zFGcH3Rz

☕️ Quartz Quartz - это мощная библиотека с открытым исходным кодом для планирования и выполнения задач по расписанию в Java-приложениях. Она предоставляет гибкие возможности для определения сложных расписаний выполнения задач и поддерживает кластеризацию. 🌐Пример: Планирование задачи резервного копирования базы данных

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.time.LocalDateTime;

public class BackupSchedulerExample {
    public static void main(String[] args) throws SchedulerException {
        // Создаем планировщик
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        // Определяем задачу
        JobDetail job = JobBuilder.newJob(DatabaseBackupJob.class)
                .withIdentity("databaseBackupJob", "backupGroup")
                .build();

        // Создаем триггер для запуска задачи каждый день в 2:00
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("dailyBackupTrigger", "backupGroup")
                .withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(2, 0))
                .build();

        // Планируем задачу с триггером
        scheduler.scheduleJob(job, trigger);

        // Запускаем планировщик
        scheduler.start();

        System.out.println("Планировщик резервного копирования запущен.");
        System.out.println("Следующее резервное копирование запланировано на: " 
                + trigger.getNextFireTime());

        // Оставляем планировщик работать
        try {
            Thread.sleep(60000); // Ждем 1 минуту для демонстрации
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Останавливаем планировщик
        scheduler.shutdown();
    }

    // Класс, представляющий задачу резервного копирования
    public static class DatabaseBackupJob implements Job {
        @Override
        public void execute(JobExecutionContext context) {
            System.out.println("Выполняется резервное копирование базы данных: " 
                    + LocalDateTime.now());
            // Здесь был бы реальный код для резервного копирования
        }
    }
}
🔐Quartz предоставляет надежное решение для планирования и выполнения задач в Java-приложениях. Его гибкость позволяет реализовывать сложные сценарии планирования, от простых периодических задач до сложных расписаний с учетом праздников, временных зон и других факторов.

👍 Тренд 2025 года — развитие без лишних затрат! Зачем платить за дорогостоящие ресурсы, если все, что тебе нужно, уже собран
👍 Тренд 2025 года — развитие без лишних затрат! Зачем платить за дорогостоящие ресурсы, если все, что тебе нужно, уже собрано в Telegram? Программисты уже переходят на новый уровень, получая доступ к лучшим материалам без единого вложения: 👩‍💻 JavaScript 👩‍💻 React 👩‍💻 Python 👩‍💻 Docker 👩‍💻 Java 🖼️ Spring 👩‍💻 C# 👩‍💻 Game Dev 👩‍💻 С/С++ 👩‍💻 DevOps 👣 GoLang 🖼️ Redis 👩‍💻 Kotlin 👩‍💻 Mob Dev 🖼️ PHP 🖥 SQL 🖼️ Swift 👩‍💻 Kubernetes В 2025 году все доступные ресурсы уже здесь, бесплатно! Подписывайся и будь в тренде, не тратя деньги на платные подписки 👍