Рубрики
Без рубрики

Записи Java 14 :: дожили ли мы до того, чтобы увидеть, как умирают добытчики и сеттеры?

Это конец очереди для добытчиков, сеттеров и проекта Ломбок? Фото Майка Кеннеди… Помечено java 14, java, функции предварительного просмотра java, записи java.

Это конец очереди для добытчиков, сеттеров и проекта Ломбок?

Фото Майк Кенилли на Расплескать

Если вы попытаетесь научить Java тысячелетию или кому-то, кто пришел с другого, менее подробного языка, вы часто можете столкнуться с сопротивлением в отношении написания геттеров, сеттеров, методов toString, equals и хэш-кода и необходимости такого большого количества шаблонного кода.

Разработчики Vintage не будут беспокоиться об этом. Мы просто привыкли поручать IDE генерировать их для нас.

Но давайте посмотрим правде в глаза: они нам не особенно нравятся . Мы просто привыкли к ним. Мы признали необходимость этих методов, но, честно говоря, все могло быть по-другому.

Java 14 запустила записи : функцию предварительного просмотра для нового типа, которая устраняет необходимость в методах getters, setters, toString, equals и hashCode. Можно создать объект с помощью нескольких строк кода.

Как это работает?

Поскольку это еще функция предварительного просмотра, мы должны включить функции предварительного просмотра в нашем компиляторе, IDE и/или Maven.

В кратких отчетах имеются следующие характеристики:

  • Они окончательны и неизменны.
  • Они могут реализовывать интерфейсы.
  • У них могут быть статические члены.
  • Они могут определять проверки.
  • Они могут определять значения по умолчанию.
  • Они принимают дженерики.

Я протестировал его, и проект доступен на моем GitHub .

Все прошло! \o/

Окончательный и неизменный

Обратите внимание, что записи не имеют классических приемников и установщиков, и поэтому невозможно изменить их значения после их назначения.

Обратите внимание на строки с 34 по 38 ниже, что чтение атрибутов выполняется без префикса “get”. Мы прямо используем имя атрибута.

import static org.junit.Assert.assertTrue;

import java.time.LocalDateTime;
import java.time.Month;
import java.util.Objects;

import org.junit.Test;

import com.danianepg.previewfeature.data.NationalHoliday;
import com.danianepg.previewfeature.data.records.CelebrationGenericRecord;
import com.danianepg.previewfeature.data.records.SpecialDate;

/**
 * Test class to verify the records' functionalities.
 * @author Daniane P. Gomes
 *
 */
public class RecordsDemoTest {

    private String name = "My Bday";
    private Integer day = 20;
    private Month month = Month.OCTOBER;
    private LocalDateTime created = LocalDateTime.now();

    private String country = "Brazil";
    private String nationalHolidayName = "Independence Day";
    private Integer nationalHolidayDay = 7;
    private Month nationalHolidayMonth = Month.SEPTEMBER;

    @Test
    public void specialDateRecord_ok() {

        SpecialDate myBday = new SpecialDate(name, day, month, created);
        boolean isNameEquals = myBday.name().equals(name);
        boolean isDayEquals = myBday.day() == day;
        boolean isMonthEquals = myBday.month() == month;
        boolean isCreatedEquals = myBday.created().equals(created);

        assertTrue(isNameEquals && isDayEquals && isMonthEquals && isCreatedEquals);
    }

    @Test
    public void specialDateRecord_equals_ok() {
        SpecialDate myBday = new SpecialDate(name, day, month, created);
        SpecialDate myBdayCopy = new SpecialDate(name, day, month, created);
        assertTrue(myBday.equals(myBdayCopy));
    }

    @Test
    public void specialDateRecord_alternativeConstructor() {
        SpecialDate myBday = new SpecialDate(name, day, month);
        boolean isCreatedNotNull = !Objects.isNull(myBday.created());
        assertTrue(isCreatedNotNull);
    }


    @Test(expected = IllegalArgumentException.class)
    public void specialDateRecord_exceptionWhenDayOutOfTheRange() {
        try {
            new SpecialDate(name, 32, month);
        } catch (IllegalArgumentException e) {
            System.out.println("Message exception: "+e.getMessage());
            throw e;
        }
    }

    @Test
    public void celebrationGenericRecord_ok() {

        CelebrationGenericRecord dateGenericClassic = new CelebrationGenericRecord<>(
                new NationalHoliday(country), nationalHolidayName, nationalHolidayDay, nationalHolidayMonth);

        boolean isInstanceOfNationalHoliday = dateGenericClassic.contents() instanceof NationalHoliday;
        boolean isCountryEquals = false;

        if (isInstanceOfNationalHoliday) {
            NationalHoliday dateClassic = (NationalHoliday) dateGenericClassic.contents();
            isCountryEquals = dateClassic.getCountry().equals(country);
        }

        assertTrue(isInstanceOfNationalHoliday && isCountryEquals);

    }

}

Интерфейсы, Статические элементы, Проверки, Значения по умолчанию

Записи совместимы с нашими классическими интерфейсами. Проверьте запись “Особая дата”, которая реализует интерфейс “Интерфейс празднования” и, следовательно, перезаписывает метод “totalDates()”. Обратите внимание на строки 13 и 48.

Для дополнительного статического элемента проверьте строку 18.

Для проверки проверки строка 28.

Для значения по умолчанию проверьте альтернативный конструктор в строке 41, который назначает текущую дату и время для созданного объекта, даже если об этом не сообщается во время создания объекта записи.

package com.danianepg.previewfeature.data.records;

import java.time.LocalDateTime;
import java.time.Month;

import com.danianepg.previewfeature.interfaces.CelebrationInterface;

/**
 * An example of a record implementing an interface, validating data, passing default values and using extra static attributes and methods.
 * @author Daniane P. Gomes
 *
 */
public record SpecialDate(String name, Integer day, Month month, LocalDateTime created) implements CelebrationInterface {

    /**
     * Additional static members
     */
    private static int totalDates;

    /**
     * Define validations for the attributtes
     * @param name
     * @param day
     * @param month
     * @param created
     */
    public SpecialDate {
        if (day < 1 || day > 31) {
            throw new IllegalArgumentException("Day must be on the interval 1-31.");
        }

        totalDates++;
    }

    /**
     * Additional constructor, to assign a default value to attribute "created"
     * @param name
     * @param day
     * @param month
     */
    public SpecialDate(String name, Integer day, Month month) {
        this(name, day, month, LocalDateTime.now());
    }

    /**
     * Additional public method to retrieve 
     */
    public int totalDates() {
        return totalDates;
    }

}

Дженерики

Записи являются гибкими и принимают дженерики! Определение можно найти ниже, а также пример того, как его использовать, доступен в тесте “| GenericRecord_ok()” класса ” RecordsDemoTest |/”.

package com.danianepg.previewfeature.data.records;

import java.time.Month;

/**
 * Generic record
 * @author Daniane P. Gomes
 *
 * @param 
 */
public record CelebrationGenericRecord(T contents, String name, Integer day, Month month) {
}

Почему это полезно?

Короткий ответ: к данным носителя.

Длинный ответ: теперь мы можем объявить простой объект передачи данных с помощью нескольких строк кода и без необходимости выполнять все церемонии, к которым мы привыкли в Java, что означает ЧИСТЫЙ код!

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

Вывод

Ну что ж тогда… неужели это конец очереди для наших любимых ненавистных добытчиков и сеттеров домашних животных? Хммм… Очевидно, еще не совсем.

Поскольку записи неизменяемы, они не могут просто заменить наши классические классы. Кроме того, еще одна проблема, которую необходимо решить, заключается в том, насколько они совместимы с такими фреймворками, как Hibernate и Spring?

Однако они помогут нам сделать код чище и меньше и в некоторых случаях они могли бы даже устранить необходимость во внешних библиотеках, таких как Lombok, как заявил Бен Эванс для Java Magazine :

“Это поможет многим приложениям сделать классы доменов более четкими и компактными. Это также поможет командам устранить множество реализаций базового шаблона, написанных вручную, и уменьшить или устранить необходимость в библиотеках, таких как Lombok “.

Однако важно иметь в виду, что это функция предварительного просмотра, и, как напоминает документация :

” Функции предварительного просмотра могут быть удалены в будущей версии или обновлены до постоянных функций языка Java.”

Я надеюсь, что они сохранят его. Скрестив пальцы.

Рекомендации

JEP 359: Записи (Предварительный просмотр)

Запись (Java SE 14 и JDK 14)

Записи поступают на Яву

Первоначально опубликовано на моя средняя страница .

Оригинал: “https://dev.to/danianepg/java-14-records-did-we-live-to-see-getters-and-setters-die-350e”