Pascal4eg / Java

 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.

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

Switch-выражения

String season = switch (month) {
    case JANUARY, FEBRUARY -> "winter";
    case MARCH, APRIL, MAY -> "spring";
    case JUNE, JULY, AUGUST -> "summer";
    case SEPTEMBER, OCTOBER, NOVEMBER -> {
        System.out.println("winter is coming!");
        yield "autumn";
    }
    case DECEMBER -> "winter";
}

Чтобы получить значение из switch-выражения, раньше приходилось создавать отдельную переменную и постоянно использовать break;.

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

Text Blocks (Текстовые блоки)

public static final String TEST_STUDENT_XML = """
    &lt;student&gt;
        &lt;name&gt;Harry Potter&lt;/name&gt;
        &lt;faculty&gt;Gryffindor&lt;/faculty&gt;
    &lt;/student&gt;
    """;

В Java 15 появилась возможность задать константу типа String состоящую из нескольких строк без использования конкатенации.

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

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

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

Guava: Google Core Libraries for Java

RangeSet<Integer> numberRangeSet = TreeRangeSet.create();

numberRangeSet.add(Range.closed(0, 2));
numberRangeSet.add(Range.closed(3, 5));
numberRangeSet.add(Range.closed(6, 8));

assertTrue(numberRangeSet.contains(1));
assertFalse(numberRangeSet.contains(9));

Guava — это набор общих библиотек Java от Google, который включает в себя новые типы коллекций (такие как multimap и multiset), неизменяемые коллекции, библиотеку графов и утилиты для параллелизма, ввода-вывода, хеширования, примитивов, строк и многого другого! Он широко используется в большинстве проектов Java в Google, а также во многих других компаниях.

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

Stream API: filter() перед map()

var list = Arrays.asList(1, 2, 3, 4, 5);
var filteredList = list.stream()
        .filter(i -> i % 2 == 0)
        .map(i -> i * 2)
        .collect(Collectors.toList());

В Stream API используйте filter() перед map(), чтобы избежать ненужной обработки.

Если у вас есть поток, который может содержать большое количество элементов, не соответствующих вашим критериям, используйте filter() перед map(), чтобы избежать ненужной обработки. Это может улучшить производительность вашего кода.

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