Статьи Утилиты Telegram YouTube VK Видео RuTube Отзывы

Compact Sources в Java

15 октября 2025

Тэги: Java.

Содержание

  1. Новый класс IO
  2. Вызов других методов
  3. Передача параметров из командной строки
  4. Использование других классов
  5. Доступность стандартной библиотеки
  6. Выводы

Java 25 принесла нам такие фичи как Compact Sources и Instance Main Methods (JEP 512). Теперь мы можем писать на Java как на скриптовом языке: без создания классов, без модификаторов доступа и без явных импортов. Это значительно снижает порог входа для новичков, ведь раньше нужно было объяснять что такое класс, что такое public, static, маccив строк.

Сравните, как выглядела самая простая программа до Java 25:

public class Main {
    public static void main(String[] args) {
        System.out.println("Привет, мир!");
    }
}

И как выглядит её эквивалент теперь:

void main() {
    IO.println("Привет, мир!");
}

Теперь фиктивная обёртка в виде класса становится необязательной, а System.out получил компактный алиас в виде IO.

На уровне компилятора тут никакой магии нет. Наши методы всё так же оборачиваются в некий класс. При этом имя такого класса удаляется из таблицы символов, чтобы нельзя было его создать с помощью new. То есть для программиста такой класс-обёртка недоступен.

Также необходимо дополнить, что сейчас не обязательно компилировать программу с помощью javac. Мы можем запускать исходники прямо из командной строки. Эта возможность появилась уже довольно давно, ещё в Java 10.

java Main.java
Привет, мир!

Отсюда кстати следует интересный вывод, что для запуска скрипта на java вам даже не нужен JDK со средствами компиляции, достаточно JRE.

Новый класс IO

Для упрощения работы с консолью у нас появился новый класс IO, который оборачивает некоторые методы из System.out и System.in. Он содержит всего пять методов:

public final class IO {
    public static void println(Object obj);

    public static void println();

    public static void print(Object obj);

    public static String readln();
    
    public static String readln(String prompt);
}

Наверняка вы помните, что считать строку из консоли в Java было чуть сложнее, чем вывести её на экран. Теперь всё это в прошлом.

Поскольку класс IO находится в пакете java.lang, то импортировать его в явном виде не требуется. Однако Compact Source файл должен находится в корневом пакете (т.е. в папке src). Это позволяет нам избавиться от объявления package.

Теперь давайте рассмотрим несколько примеров.

Вызов других методов

Допустим, я сначала хочу запросить имя у пользователя, чтобы затем его поприветствовать:

// почти javascript
void main() {
    var name = IO.readln("Как Вас зовут? ");
    IO.println("Добро пожаловать, " + name + "!");
}

Ничто не мешает мне создавать другие методы в этом же файле:

void main() {
    var name = IO.readln("Как Вас зовут? ");
    displayMessage(name);
}

void displayMessage(String name) {
    IO.println("Добро пожаловать, " + name + "!");
}

Передача параметров из командной строки

Как и раньше, я могу передать параметры из командной строки как параметры метода main:

void main(String[] args) {
    if (args.length > 1) {
        displayMessage(args[0]);
    } else {
        // параметры командной строки не указаны
        displayMessage(IO.readln("Как Вас зовут? "));
    }
}

void displayMessage(String name) {
    IO.println("Добро пожаловать, " + name + "!");
}

Тогда при вызове программы из консоли я могу перечислить все параметры метода через пробел:

java Hello.java Борис
Добро пожаловать, Борис!

Использование других классов

Я могу использовать не только методы из текущего файла, но и соседние классы, если они лежат в той же папке src.

// файл src/Person.java
record Person(
        String name,
        int age
) {
}

// файл src/Hello.java
void main() {
    var person = new Person("Анна", 25);
    IO.println("Добро пожаловать, " + person.name() + "!");
}

Никаких импортов.

Доступность стандартной библиотеки

Вводом-выводом дело не ограничивается. В скоупе Compact Source мне также доступны все стандартные классы и коллекции (List, Set, Map) без явного импорта.

void main() {
    var persons = List.of(
            new Person("Анна", 23),
            new Person("Фёдор", 34),
            new Person("Николай", 27)
    );
    var average = persons.stream()
            .mapToInt(Person::age)
            .average();
    IO.println("Средний возраст: " + average); // 28
}

Выводы

Разработчики Java уже давно взяли курс на сокращение boiler plate кода, последовательно вводя лямбды, стримы, var, List.of(), record и т.п.

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


См. также


Комментарии

Добавить комментарий

×

devmark.ru