@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.
Читать дальше