Урок 1 из 11 старт около 25 мин

JShell: пробуем Java без проекта и сборки

Запускаем интерактивную оболочку из состава JDK, вычисляем выражения, объявляем переменные и методы и учимся быстро проверять идеи, не создавая проект.

Зачем нужен JShell

Обычная Java-программа требует файла, класса и метода main, а иногда ещё и системы сборки. Для проверки одной идеи это слишком дорого. JShell — интерактивная оболочка, которая входит в состав JDK начиная с девятой версии: вы вводите выражение, нажимаете Enter и сразу видите результат. Именно так удобнее всего знакомиться с новыми возможностями языка, о которых пойдёт речь в следующих уроках.

JShell не заменяет проект и тесты. Он нужен, чтобы проверить гипотезу за минуту, посмотреть, что возвращает метод стандартной библиотеки, или показать коллеге пример, не открывая среду разработки.

Запуск и первые команды

Убедитесь, что установлен JDK 21 и каталог bin добавлен в переменную PATH. Затем откройте терминал и запустите оболочку:

$ jshell
|  Welcome to JShell -- Version 21.0.11
|  For an introduction type: /help intro

jshell> 2 + 2
$1 ==> 4

jshell> "Фортуна".length()
$2 ==> 7

Служебные сообщения оболочка выводит по-английски: русской локализации у JShell нет ни в одной сборке JDK 21. Каждый результат без имени JShell кладёт во временную переменную вида $1, $2. Ими можно пользоваться дальше, но лучше сразу давать переменным имена:

jshell> int years = 2026 - 1995
years ==> 31

jshell> String greeting = "Добрый день"
greeting ==> "Добрый день"

jshell> greeting + ", вам " + years
$5 ==> "Добрый день, вам 31"

Обратите внимание: точку с запятой в конце одиночного выражения или объявления можно не ставить. Внутри тела метода или цикла она обязательна, как и в обычной Java. Имена переменных и методов в примерах написаны латиницей: Java допускает и кириллицу, но в рабочих проектах так не делают.

Методы и повторное использование

В JShell можно объявить метод без класса. Оболочка сообщает, что метод создан, и с этого момента его можно вызывать:

jshell> int square(int n) {
   ...>     return n * n;
   ...> }
|  created method square(int)

jshell> square(12)
$7 ==> 144

Если объявить метод с тем же именем и сигнатурой ещё раз, JShell тихо заменит старое определение новым. Это удобно для доработки, но легко потерять из виду, какая версия сейчас действует. Команда /methods показывает все объявленные методы, /vars — переменные, /list — весь введённый код с номерами фрагментов.

Служебные команды, которые стоит запомнить

КомандаЧто делает
/helpСправка по командам; /help intro — короткое введение.
/listПоказывает все введённые фрагменты с номерами.
/edit 3Открывает фрагмент номер 3 в простом редакторе.
/drop 3Удаляет фрагмент номер 3.
/save urok.jshСохраняет сессию в файл, /open urok.jsh загружает её обратно.
/importsСписок импортов; по умолчанию уже подключены java.util, java.io и другие частые пакеты.
/resetОчищает состояние без выхода.
/exitЗавершает работу.

Клавиша Tab дополняет имена методов и показывает варианты. Если нажать Tab после открывающей скобки вызова, JShell покажет сигнатуры перегрузок, а повторное нажатие — документацию.

Пример: пробуем стандартную библиотеку

Допустим, вы не помните, как разбить строку на слова и посчитать их. Вместо поиска в интернете достаточно нескольких строк:

jshell> var text = "Java стала проще, чем о ней рассказывают"
text ==> "Java стала проще, чем о ней рассказывают"

jshell> text.split("\\s+").length
$9 ==> 7

jshell> java.util.Arrays.stream(text.split("\\s+")).filter(w -> w.length() > 4).toList()
$10 ==> [стала, проще,, рассказывают]

Результат подсказывает и следующую проблему: запятая прилипла к слову «проще». Так JShell помогает увидеть ошибку до того, как она попадёт в программу.

Частая ошибка

Начинающие пытаются объявить в JShell метод main и ждут, что он выполнится. Оболочка просто создаст метод, как любой другой. Чтобы запустить код, вызовите метод явно: main(new String[0]). Ещё проще — писать нужные выражения напрямую.

Следующий шаг: программа в одном файле

Когда эксперимент перерастает в программу, сохраните её в файл и запустите без компиляции отдельной командой. Начиная с Java 11 команда java умеет компилировать и исполнять единственный исходный файл:

// Файл Privet.java
public class Privet {
    public static void main(String[] args) {
        System.out.println("Привет из одного файла");
    }
}
$ java Privet.java
Привет из одного файла

Этого достаточно для всех примеров курса. Систему сборки вроде Maven или Gradle стоит подключать, когда появляются зависимости и тесты.

Попробуйте сами

  1. Запустите JShell и объявите метод boolean isPalindrome(String s), который возвращает true для строк, одинаково читающихся в обе стороны. Подсказка: new StringBuilder(s).reverse().toString().
  2. Проверьте метод на словах «шалаш», «Фортуна» и на строке с пробелами «А роза упала на лапу Азора». Подумайте, как убрать пробелы и регистр перед сравнением.
  3. Сохраните сессию командой /save palindrom.jsh, выйдите, запустите JShell снова и восстановите её через /open.