Проблема Одной из проблем Java является ее многословность и объем требуемого стандартного кода.
Это общеизвестно.
Давайте посмотрим на простой класс Кот на Яве.
Мы хотим, чтобы каждый объект Cat имел следующие атрибуты (поля):
- Имя
- Количество жизней
- Цвет
Это уже довольно долго, не так ли? Но будет еще хуже.public final class Cat { private final String name; private final int numberOfLives; private final String color; public Cat(String name, int numberOfLives, String color) { this.name = name; this.numberOfLives = numberOfLives; this.color = color; } public String getName() { return name; } public int getNumberOfLives() { return numberOfLives; } public String getColor() { return color; } }
Мы также хотим иметь базовую реализацию равно() И хэш-код() .
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Cat cat = (Cat) o;
return numberOfLives == cat.numberOfLives &&
Objects.equals(name, cat.name) &&
Objects.equals(color, cat.color);
}
@Override
public int hashCode() {
return Objects.hash(name, numberOfLives, color);
}
Мы уже закончили? Не совсем, нам все еще нужен хороший метод toString(): @Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", numberOfLives=" + numberOfLives +
", color='" + color + '\'' +
'}';
}
И наконец мы всё сделали.
Это около пятидесяти строк кода! Писать довольно больно (хотя ваша IDE может здесь помочь) и тяжело читать.
Хуже всего то, что в этом шаблонном коде трудно найти дополнительную функциональность (например, новые методы).
В этих пятидесяти строках есть только три строки, которые действительно интересны и несут некоторую информацию: private final String name;
private final int numberOfLives;
private final String color;
Остальное — это простой шаблонный код, который предсказуем и может автоматически генерироваться на основе этих трех строк.
Ваша IDE может это сделать, и есть такие инструменты, как Ломбок кто может сделать это и для вас.
В Java вы часто используете классы, которые просто хранят данные, как наш.
Кот .
Реализация всегда практически одинаковая — набор полей, геттеров, равно() , хэш-код() И нанизывать() .
Часто бывает полезно по возможности оставить их без изменений, что имеет множество преимуществ.
Но написание и чтение таких классов — это большой труд, поскольку они содержат много кода.
И это подвержено ошибкам.
Кто-нибудь знает, правильный ли ваш код для хэш-код() И равно() ?
Рекорды
Ява 14 пытается решить эту проблему, вводя новый тип под названием Записывать , это описано в JEP 359: Записи (предварительный просмотр) .
Тот же 50-строчный класс из примера выше можно записать примерно так: public record Cat(String name, int numberOfLives, String color) { }
Код намного меньше, верно? Функционал тот же, что и в нашем предыдущем примере — у нас есть:
- Неизменяемый класс с тремя полями
- Конструктор назначает эти поля
- Геттеры
- Equals(), hashCode() и toString()
public final class Cat extends java.lang.Record {
private final java.lang.String name;
private final int numberOfLives;
private final java.lang.String color;
public Cat(java.lang.String name, int numberOfLives, java.lang.String color) { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public final int hashCode() { /* compiled code */ }
public final boolean equals(java.lang.Object o) { /* compiled code */ }
public java.lang.String name() { /* compiled code */ }
public int numberOfLives() { /* compiled code */ }
public java.lang.String color() { /* compiled code */ }
}
Вы можете видеть, что код почти такой же, как наш старый.
Кот .
Заметным исключением является то, что методы получения сгенерированных полей называются иначе, чем обычно – вместо получитьЦвет() Здесь есть только цвет() .
Класс также расширяется java.lang.Запись .
Выполнение равно() считает две записи равными, если они одного типа и имеют одинаковые значения.
Выполнение нанизывать() печатает нашу запись следующим образом: Cat[name=Fluffy, numberOfLives=9, color=White]
Хотя эти методы предоставляются автоматически, при необходимости их можно переопределить.
Ограничения
Существуют некоторые недостатки и ограничения записи, о которых вам следует знать.
- Записи не могут расширять какой-либо класс, но могут реализовывать интерфейсы.
- Записи не могут быть абстрактными.
- Записи являются окончательными; они не могут быть унаследованы
- Вы можете объявить дополнительные поля в теле сообщения, но только если они статичные.
Добавление методов
Хотя записи в основном используются как простые носители данных, вы можете объявить свои собственные методы.Конечно, поскольку записи неизменяемы, вы не можете изменить какое-либо состояние, но это все равно может быть полезно.
Например: public record Cat(String name, int numberOfLives, String color) {
public boolean isAlive() {
return numberOfLives >= 0;
}
}
Вы также можете добавить статические методы.
Пользовательские (Пользовательские) конструкторы
По умолчанию новые записи содержат только конструктор, который требует, чтобы все поля записи были параметрами.
Например, наш класс Cat с тремя полями должен быть построен следующим образом: Cat cat = new Cat("Fluffy", 9, "White");
Что, если некоторые параметры могут быть необязательными — если мы их не предоставляем, можно использовать какое-то значение по умолчанию.
В нашем случае количество жизней для новых кошек, скорее всего, всегда будет равно 9. Мы можем создать дополнительный конструктор, принимающий только имя и цвет, а количество жизней можно установить равным 9 в качестве значения по умолчанию.
Конечно, конструктор со всеми тремя полями все еще существует и доступен.
public record Cat(String name, int numberOfLives, String color) {
public Cat(String name, String color) {
this(name, 9, color);
}
}
Для нас автоматически генерируется конструктор со всеми полями.
Но иногда вам нужно сделать там какую-то собственную логику.
Например, проверка ввода.
Вы можете объявить свой, если нужно, конструктор со всеми полями: public record Cat(String name, int numberOfLives, String color) {
public Cat(String name,int numberOfLives, String color) {
if(numberOfLives < 0) {
throw new IllegalArgumentException("Number of lives cannot be less than 0.");
}
if(numberOfLives > 9) {
throw new IllegalArgumentException("Cats cannot have that many lives.");
}
this.name = name;
this.numberOfLives = numberOfLives;
this.color = color;
}
}
Если вы переопределяете конструктор со всеми полями, указанными в записи (канонический конструктор), вы можете использовать объявление без записи параметров.
Их по-прежнему можно использовать, но код станет короче.
public record Cat(String name, int numberOfLives, String color) {
// This is the same as public Cat(String name, int numberOfLives, String color)
public Cat {
// name, numberOfLives and color available here
}
}
Самоанализ во время выполнения
В java.lang.Класс были добавлены два новых метода, функциональные возможности которых связаны с записями.Первый называется isRecord() .
Все довольно просто, можно просто проверить, является ли какой-то объект записью или нет: Cat cat = new Cat("Fluffy", 9, "White");
if(cat.getClass().
isRecord()) { //.
}
Другой ПолучитьЗаписьКомпоненты() .
Вы бы назвали это так же, как в примере выше.
Возвращает список java.lang.reflect.RecordComponent .
По сути, это список всех полей записи с такой информацией, как:
- Имя
- Тип
- Аксессор
- Аннотации
Попробуй сам!
Если вы хотите попробовать эту функцию самостоятельно, вы уже можете это сделать, хотя Java 14 еще не выпущена (по состоянию на 2 февраля 2020 г.).
Функция предварительного просмотра
Функциональность записей доступна в Java 14. Однако в настоящее время это только предварительная версия.Что это значит?
Предварительный просмотр функций языка и виртуальной машины — это новая функция платформы Java SE, которая полностью определена, реализована, но в то же время определена как временная.Такие функции предусмотрены в JDK, но по умолчанию не включены.Он включен в выпуск JDK для предоставления разработчикам обратной связи на основе фактического использования; это может привести к тому, что он станет постоянным в будущей платформе Java SE. Перед следующим выпуском функции JDK будут проанализированы сильные и слабые стороны этой функции в реальном мире, чтобы решить, будет ли эта функция играть долгосрочную роль в платформе Java SE, и если да, то нужно ли ее дорабатывать.
.
Следовательно, функциям может быть присвоен окончательный и постоянный статус (с оговорками или без них), или пройти дополнительный период предварительного просмотра (с оговорками или без них), или они могут быть удалены.
Вы должны явно разрешить им их использовать.
Излишне говорить, что он предназначен не для промышленного использования, а скорее для оценки и экспериментирования, поскольку в будущем выпуске он может быть удален или сильно изменен.
Чтобы попробовать эту функцию самостоятельно, вам необходимо установить JDK 14.
Настройка IntelliJ IDEA
В IntelliJ IDEA вы можете включить функции предварительного просмотра в меню.Файл → Структура проекта .
Чтобы использовать записи в IntelliJ IDEA, вам понадобится версия 2020.1 и позже.
По состоянию на 2 февраля 2020 г.
он доступен в виде предварительной сборки ( Сборка программы раннего доступа ).
В настоящее время IDEA имеет базовую поддержку записей, но полная поддержка должна быть доступна в релизной версии.
Ручная компиляция
Альтернативой является сборка проекта вручную.
Затем вам необходимо предоставить javac следующие параметры: javac --release 14 --enable-preview .
Это сделано для целей компиляции.
Во время выполнения вы просто предоставляете --enable-предварительный просмотр java --enable-preview .
Maven-проекты
Для сборок Maven вы можете использовать следующую конфигурацию: <build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>14</release>
<compilerArgs>
--enable-preview
</compilerArgs>
```14</source>
<target>14</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>--enable-preview</argLine>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<argLine>--enable-preview</argLine>
</configuration>
</plugin>
</plugins>
</build>
Теги: #программирование #java
-
Могут Ли Raid-Системы Выйти Из Строя?
19 Oct, 24 -
Что Делать С Компьютерными Проводами
19 Oct, 24 -
Мы Запускаем Synology На Esxi
19 Oct, 24 -
Развитие Предметного Мышления У Учащихся
19 Oct, 24 -
Я Ничего Не Понимаю В Seo
19 Oct, 24