Skip to content

Latest commit

 

History

History
159 lines (128 loc) · 5.29 KB

File metadata and controls

159 lines (128 loc) · 5.29 KB

Безымянные переменные (Unnamed Patterns and Variables) (java 21+)

Безымянные переменные, обозначаются символом _ (подчеркивание)

int acc = 0;
for (Order _ : orders) {
    if (acc < LIMIT) {
        … acc++ …
    }
}

В примере важен факт наличия переменное, но ее имя можно не придумывать, потому что сама переменная не нужна
Аналогичное использование: безымянные try-catch. Пример:

String s = // ...
try {
    int i = Integer.parseInt(s);
    // ....
} catch (NumberFormatException _) {
    System.out.println("Bad number: " + s);
}

Случаи в которых можно использовать безымянные переменные:

  • Локальная переменная в блоке
  • Объявление ресурса в try-with-resources
  • Заголовок for statement
  • Заголовок улучшенного цикла for
  • Исключение в блоке catch
  • Параметр лямбда-выражения
  • Переменная паттерна (см ниже)

Параметры методов не могут быть безымянными

Безымянные паттерны, пример:

if (r instanceof ColoredPoint(Point(int x, int y), _)) {
    // Используются только x и y
}

Класс ColoredPoint содержит точку (Point) и цвет (Color)
Разработчику нужны только координаты x, y, а цвет в данном случае не важен, поэтому его можно указать через безымянную переменную
Если требуется цвет, то код будет выглядеть так:

if (r instanceof ColoredPoint(Point(int x, int y), Color c)) {
    // Используются x, y и цвет
}

Если Color c не используется, то получим Warning: unused c

Аналогичный безымянные паттерн, с указание типа:

if (r instanceof ColoredPoint(Point(int x, int y), Color _)) {
    // ...
}

Мы указали класс Color, но саму переменную оставили безымянной

Безымянные паттерны сочетаются с конструкцией switch, пример:

switch (box) {
    case Box(RedBall _), Box(BlueBall _) -> processBox(box);
    case Box(GreenBall _)                -> stopProcessing();
    case Box(_)                          -> pickAnotherBox();
}

Дополнительные примеры использования:

... instanceof Point(int x, _)
case Point(int x, _)
int _ = q.remove();
} catch (NumberFormatException _) {
(int x,int _)->x+x

Безымянные классы (Unnamed Classes and Instance Main Methods) (java 21+)

Теперь в режиме preview можно запускать программы с методами main(), которые не являются public static и у которых нет параметра String[] args.
В таком случае JVM сама создаст экземпляр класса (у него должен быть не-private конструктор без параметров) и вызовет у него метод main().

class HelloWorld {
    void main() {
        System.out.println("Hello, World!");
    }
}

Протокол запуска будет выбирать метод main() согласно следующему приоритету:

  1. static void main(String[] args)
  2. static void main()
  3. void main(String[] args)
  4. void main()

Кроме того, можно писать программы и без объявления класса вовсе:

String greeting = "Hello, World!";

void main() {
    System.out.println(greeting);
}

В таком случае будет создан неявный безымянный класс (не путать с анонимным классом), которому будут принадлежать метод main() и другие верхнеуровневые объявления в файле:

// class <some name> { ← неявно
String greeting = "Hello, World!";

void main() {
    System.out.println(greeting);
}
// }

Безымянный класс является синтетическим и final. Его simple name является пустой строкой:

void main() {
    System.out.println(getClass().isUnnamed()); // true
    System.out.println(getClass().isSynthetic()); // true
    System.out.println(getClass().getSimpleName()); // ""
    System.out.println(getClass().getCanonicalName()); // null
}

При этом имя класса совпадает с именем файла, но такое поведение не гарантируется.


Ссылки: