Новое в Java: можно ли отказаться от типов данных?

Java
Новое в Java: можно ли отказаться от типов данных?

Давным-давно, когда мы писали код, нам приходилось тщательно учитывать тип данных переменных, таких как следующие:image.png

перечислить: несмотря на то, что тип перечисления добавлен в JDK 5, константа типа CONSTANT_Class_info пула констант файла Class не претерпела никаких семантических изменений, она по-прежнему является символической ссылкой, представляющей класс или интерфейс, не было добавлено никакого перечисления, и нет «CONSTANT_Enum_info». "был добавлен. ", и т.д. константы "ссылки на символы перечисления". Таким образом, использование ключевого слова enum для определения констант, хотя из синтаксиса Java выглядит как определение класса с помощью ключевого слова class и определение интерфейса с помощью ключевого слова interface, на самом деле это иллюзия, созданная компилятором Javac.С точки зрения байт-кода, перечисление — это обычный класс Java, который наследуется от java.lang.Enum и автоматически генерирует методы values() и valueOf(), поэтому перечисления также классифицируются как ссылочные типы..

Однако, когда дело доходит до JDK 10, у нас есть новые опции, которые недавно добавлены в JDK 10.varФункция вывода локальной переменной, мы можем с радостью забыть о типе данных, используя ее, так как же она используется? Дальше посмотрим вместе.

1. Используйте сравнение

Далее воспользуемся методом сравнения с опытомvarэффект.

Сценарий 1: определение строк

Старое написание:

String str = "Hello, Java.";

Новое написание:

var s = "Hello, Java.";

PS: старая запись здесь относится к версии до JDK 10, а новая запись относится к версии после JDK 10 (включая JDK 10).

Сценарий 2: добавление значений

Старое написание:

int num1 = 111;
double num2 = 555.666d;
double num3 = num1 + num2;
System.out.println(num3);

PS: При столкновении с добавлением разных типов (int+ double), происходит повышение типа данных, поэтомуnum3будет обновлен доdouble тип.

Новое написание:

var n1 = 111L;
var n2 = 555.666;
var n3 = n1 + n2;
System.out.println(n3);

Сценарий 3: Сбор

Старое написание:

List<Object> list = new ArrayList<>();
list.add("Hello");
list.add("Java");

Новое написание:

var list = new ArrayList<>();
list.add("Hello");
list.add("Java");

Сценарий 4: Цикл

Старое написание:

for (Object item : list) {
    System.out.println("item:" + item);
}
for (int i = 0; i < 10; i++) {
    // do something...
}

Новое написание:

for (var item : list) {
    System.out.println("item:" + item);
}
for (var i = 0; i < 10; i++) {
    // do something...
}

Сценарий 5: Использование с Lambda

Старое написание:

List<Object> flist = list.stream().filter(v ->
                v.equals("Java")).collect(Collectors.toList());
System.out.println(flist);

Новое написание:

var flist = list.stream().filter(v ->
            	v.equals("Java")).collect(Collectors.toList());
System.out.println(flist);

2. Анализ преимуществ

Из приведенного выше примера мы видим, чтоvarимеютДва очевидных преимущества: улучшенная читаемость кода и выравнивание имен..

① Улучшенная читаемость

мы не используемvarРаньше, если имя типа было очень длинным, происходило следующее:

InternationalCustomerOrderProcessor<AnonymousCustomer, SimpleOrder<Book>> orderProcessor = 
    createInternationalOrderProcessor(customer, order);

Когда каждая строка ограничена 150 символами, имя переменной будет нажата на следующую строку для отображения, поэтому читаемость всего кода становится очень низкой. но когда мы используемvarПосле этого код становится таким:

var orderProcessor = createInternationalOrderProcessor(customer, order);

Как видно из приведенного выше кода, когда тип длиннее,var(читаемость) тем больше значение.

② Выравнивание имени

не используетсяvarКогда возникает следующая ситуация, код выглядит следующим образом:

// 显式类型
No no = new No();
AmountIncrease<BigDecimal> more = new BigDecimalAmountIncrease();
HorizontalConnection<LinePosition, LinePosition> jumping =
  new HorizontalLinePositionConnection();
Variable variable = new Constant(6);
List<String> names = List.of("Java", "中文社群");

в использованииvarПосле этого код такой:

var no = new No();
var more = new BigDecimalAmountIncrease();
var jumping = new HorizontalLinePositionConnection();
var variable = new Constant(6);
var names = List.of("Java", "中文社群");

Из приведенного выше кода видно, что использованиеvarПосле этого имена выровнялись и весь код стал элегантнее.

3. Правила использования и контрпримеры

varРеализация взята из JEP 286 (предложение по улучшению 286), подробности по адресу:openjdk.java.net/jeps/286

Из названия JEP 286, "Вывод типа для локальных переменных",varможет использоваться только в объявлениях локальных переменных, т.е.varДолжны быть соблюдены следующие условия:

  • Его можно использовать только для локальных переменных;
  • Он должен быть инициализирован при объявлении;
  • Нельзя использовать как параметры метода и глобальные переменные (переменные класса).

ПС: потому чтоvarРеализации должны делать вывод типа из кода справа, поэтому ему нельзя присвоить значение null или неинициализировать.

Пример счетчика 1: неинициализированный и назначенный нуль

image.png image.png

Контрпример 2: промежуточное изменение типа

image.png

Пример счетчика 3: глобальные переменные

image.png

Пример счетчика 4: как возвращаемое значение

image.png

4. Принципиальный анализ

После предыдущего использования имеемvarУже есть предварительное понимание, ноvarКаков принцип реализации?

Чтобы понять, как это работает, мы скомпилировали следующий код (используя командуjavac MainTest.java):image.pngЗатем мы используем инструмент декомпиляции, чтобы открыть обнаружение скомпилированного класса:varОн был заменен определенным типом данных, как показано на следующем рисунке:image.pngИз этого мы можем сделать вывод:varРеализация ключевого слова тесно связана с его названием,varЭто только вывод локального типа, он действителен только во время кодирования Java и во время компиляции, когда класс компилируется в файл класса,varОн станет определенным типом данных (путем вывода).Таким образом, мы можем положитьvarОбычно понимаемый как синтаксический сахар Java, его использование позволяет нам быстро и элегантно реализовывать бизнес-код, ноvarОн не существует на уровне байт-кода.

Суммировать

В этой статье мы знакомимvar(вывод локального типа), который можно использовать для локальных переменных,for,LambdaОбъявление переменной , но его нельзя использовать в объявлении глобальных переменных, а также нельзя использовать в качестве возвращаемого значения метода, и оно должно быть инициализировано во время объявления (и не может быть присвоено значение null). использоватьvarЭто может эффективно улучшить читабельность и выравнивание имен кода.Его принцип реализации заключается в выполнении вывода типа через код с правой стороны знака равенства во время компиляции, а затем преобразованиеvarЗаменяется на определенный тип данных.

Подпишитесь на официальный аккаунт «Сообщество китайского языка Java» и отправьте «Интервью», чтобы получить последние материалы обзора интервью, которые я собрал.