Pascal4eg / Java

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

@Value Spring annotation

import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Arrays;

@Service
public class MyService {
    @Value("string value")
    private String stringValue;
    @Value("${value.from.file}")
    private String valueFromFile;
    @Value("${systemValue}")
    private String systemValue;
    @Value("${unknown. param: some default}")
    private String someDefault;
    @Value("${priority}")
    private String prioritySystemProperty;
    @Value("${listOfValues}")
    private String[] valuesArray;

    @PostConstruct
    private void postConstruct() {
        System.out.println(stringValue); // string value
        System.out.println(valueFromFile); // Value got from the file
        System.out.println(systemValue); // systemValue
        System.out.println(someDefault); //some default
        System.out.println(prioritySystemProperty); // high
        Arrays.stream(valuesArray).forEach(System.out::println); // A B C
    }
}

Эту аннотацию можно использовать для ввода значений в поля в bean-компонентах, управляемых Spring, и ее можно применять на уровне поля или параметра конструктора/метода.

Читать дальше

Запечатанные классы (Sealed class)

public sealed class Color permits Red, Green, Blue { 

}

public sealed class Red extends Color permits Ruby, Raspberry, Cherry {

}

public non-sealed class Green extends Color {

}

public final class Blue extends Color {

}

Sealed class дословно переводится как «запечатанный класс». В этом классе нужно сразу объявить список классов-наследников, потому что кроме них наследников быть не может.

Читать дальше

instanceof в Java 16

Object string = "this is string!";
if (string instanceof String realString) {
    System.out.println(realString);
}
Object object = 42;
if (!(object instanceof Number number)) {
    throw new IllegalArgumentException("this is not a Number!");
}
System. out.println (number);

Чтобы проверить, к какому классу относится объект, используют оператор instanceof. Если нужно проверить объект и привести его к нужному классу, раньше писали условие с instanceof, объявляли переменную проверяемого типа и присваивали ей проверяемый объект, предварительно приведя его к проверяемому классу.

Читать дальше

Множественная реализация интерфейсов с одинаковыми методами по умолчанию

interface Magician {
    default String getInfo() {
        return "Magician";
    }
}

interface QuidditchPlayer {
    default String getInfo() {
        return "QuidditchPlayer";
    }
}

static class HarryPotter implements Magician, QuidditchPlayer {
    @Override
    public String getInfo() {
        return Magician.super.getInfo() + ", " + QuidditchPlayer.super.getInfo();
    }
}

public static void main(String[] args) {
    HarryPotter harryPotter = new HarryPotter();
    System.out.println(harryPotter.getInfo());
    // Magician, QuidditchPlayer
}

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

Читать дальше

Reflection API

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionExample {
    public static void main(String[] args) throws Exception {
        // Получение объекта Class для класса Person
        Class<?> personClass = Class.forName("com.example.Person");

        // Получение информации о полях класса
        Field[] fields = personClass.getDeclaredFields();
        for (Field field : fields) {
            System.out.println("Field: " + field.getName() + ", Type: " + field.getType());
        }
        
        // Получение информации о методах класса и вызов метода
        Method method = personClass.getDeclaredMethod("getName");
        Object person = personClass.newInstance();
        Object result = method.invoke(person);

        System.out.println("Result of getName(): " + result);
    }
}

Reflection API в Java предоставляет средства для анализа и манипуляции классами, методами, полями и другими элементами программы во время выполнения. Это позволяет программам получать информацию о структуре классов и объектов, вызывать методы, создавать экземпляры классов и даже изменять их состояние во время выполнения. Reflection API является мощным инструментом, но также может быть опасным и требует осторожного использования.

Читать дальше

Default Methods in Interfaces

interface Vehicle {
    double getSpeed();
    default double getSpeedInMiles() {
        return getSpeed() * 0.621371;
    }
}

static class Car implements Vehicle {
    @Override
    public double getSpeed() {
        return 100;
    }
}

public static void main(String[] args) {
    Car car = new Car();
    System.out.println("Speed in km/h " + car.getSpeed());
    // Speed in km/h 100.0
    System.out.println("Speed in mph " + car.getSpeedInMiles());
    // Speed in mph 62.137100000000004
}

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

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

Читать дальше

Внедрение зависимостей (Dependency Injection)

@Service
public class Toyota implements Car {

    @Autowired
    private Engine engine;

    @Override
    public String getInfo() {
        return "Model: Toyota, Engine: " + engine.getInfo();
    }
}

Внедрение зависимостей (Dependency Injection) — это шаблон проектирования, который способствует слабой связи между компонентами системы. С помощью внедрения зависимостей вы можете внедрять зависимости в класс вместо того, чтобы создавать их внутри класса, что снижает сложность и зависимости вашего кода.

Читать дальше

HashMap

// Создание и заполнение HashMap
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("one", 1);
hashMap.put("two", 2);
hashMap.put("three", 3);

// Получение значения по ключу
int value = hashMap.get("two");
System.out.println("Value for key 'two': " + value);

HashMap - это реализация интерфейса Map, которая представляет собой структуру данных, которая позволяет хранить пары ключ-значение и обеспечивает эффективный доступ к значениям по ключу. HashMap основан на хеш-таблице, что позволяет достигать высокой производительности при операциях вставки, удаления и поиска элементов. Вот как это работает:

Читать дальше

Netty

Netty - это мощный и высокопроизводительный фреймворк для разработки сетевых приложений на языке Java. Он предоставляет асинхронное и событийно-ориентированное программирование для создания масштабируемых сетевых приложений, таких как серверы, прокси, клиенты и другие.

Читать дальше

try-with-resources

try (Connection cnn = dataSource. getConnection();
     PreparedStatement stmt = cnn.prepareStatement("SELECT * FROM operation");
     ResultSet rs = stmt.executeQuery()) {
    processOperations(rs);
} catch (Exception e) {
    LOGGER.error("Database error", e);
}

Благодаря конструкции "try-with-resources" вы можете элегантно и безопасно управлять ресурсами, такими как потоки, сокеты или другие объекты, требующие явного закрытия после использования. Это улучшение ввода-вывода позволяет автоматически закрывать открытые ресурсы после завершения блока try.

Читать дальше