Spec-Zone.ru › OpenJDK 24

Пакет jdk.jshell

package jdk.jshell
Предоставляет интерфейсы для создания инструментов, таких как цикл "Чтение-Вычисление-Вывод" (REPL), который интерактивно вычисляет "фрагменты" кода языка программирования Java. Где "фрагмент" — это одно выражение, оператор или объявление. Эта функциональность может быть использована для улучшения инструментов, таких как IDE, или может быть автономной.

JShell — центральный класс. Экземпляр JShell хранит состояние вычисления, которое включает в себя текущий набор фрагментов исходного кода и состояние выполнения, которое они произвели.

Каждый фрагмент исходного кода представлен экземпляром подкласса Snippet. Например, оператор представлен экземпляром StatementSnippet, а объявление метода представлено экземпляром MethodSnippet. Фрагменты создаются при вызове JShell.eval(String) с вводом, который включает один или несколько фрагментов кода.

Любое изменение в состоянии компиляции фрагмента сообщается с помощью SnippetEvent. Существует три основных типа изменений в состоянии фрагмента: он может быть создан с помощью eval, он может быть удален из активного состояния исходного кода с помощью JShell.drop(jdk.jshell.Snippet), и его состояние может быть обновлено в результате изменения состояния другого фрагмента. Например: при наличии js, экземпляра JShell, выполнение js.eval("int x = 5;") добавит переменную x в состояние исходного кода и сгенерирует событие, описывающее создание VarSnippet для x. Затем выполнение js.eval("int timesx(int val) { return val * x; }") добавит метод в состояние исходного кода и сгенерирует событие, описывающее создание MethodSnippet для timesx. Предположим, что varx хранит фрагмент, созданный первым вызовом eval, выполнение js.drop(varx) сгенерирует два события: одно для изменения состояния фрагмента переменной на DROPPED и одно для обновления фрагмента метода (который теперь имеет неразрешенную ссылку на x).

Конечно, для любого общего применения API входные данные не будут фиксированными строками, а будут поступать от пользователя. Ниже приведен очень упрощенный пример того, как API может быть использован для реализации REPL.

 
     import java.io.ByteArrayInputStream;
     import java.io.Console;
     import java.util.List;
     import jdk.jshell.*;
     import jdk.jshell.Snippet.Status;

     class ExampleJShell {
         public static void main(String[] args) {
             Console console = System.console();
             try (JShell js = JShell.create()) {
                 do {
                     System.out.print("Enter some Java code: ");
                     String input = console.readLine();
                     if (input == null) {
                         break;
                     }
                     List<SnippetEvent> events = js.eval(input);
                     for (SnippetEvent e : events) {
                         StringBuilder sb = new StringBuilder();
                         if (e.causeSnippet() == null) {
                             //  We have a snippet creation event
                             switch (e.status()) {
                                 case VALID:
                                     sb.append("Successful ");
                                     break;
                                 case RECOVERABLE_DEFINED:
                                     sb.append("With unresolved references ");
                                     break;
                                 case RECOVERABLE_NOT_DEFINED:
                                     sb.append("Possibly reparable, failed  ");
                                     break;
                                 case REJECTED:
                                     sb.append("Failed ");
                                     break;
                             }
                             if (e.previousStatus() == Status.NONEXISTENT) {
                                 sb.append("addition");
                             } else {
                                 sb.append("modification");
                             }
                             sb.append(" of ");
                             sb.append(e.snippet().source());
                             System.out.println(sb);
                             if (e.value() != null) {
                                 System.out.printf("Value is: %s\n", e.value());
                             }
                             System.out.flush();
                         }
                     }
                 } while (true);
             }
             System.out.println("\nGoodbye");
         }
     }
 
 

Для регистрации на события изменения состояния используйте JShell.onSnippetEvent(java.util.function.Consumer). Эти события генерируются только eval и drop, значения возврата этих методов — список событий, сгенерированных этим вызовом. Таким образом, как и в примере выше, события могут использоваться без регистрации на получение событий.

Если вы экспериментируете с этим примером, вы увидите, что пропуск точки с запятой в операторе или объявлении переменной приведет к ошибке. Незавершенная запись (например, желаемый многострочный метод) также завершится ошибкой после одной строки. Утилиты в SourceCodeAnalysis предоставляют анализ границ и полноты исходного кода для решения таких случаев. SourceCodeAnalysis также предоставляет предлагаемые дополнения к вводу, что может использоваться для ввода с помощью клавиши Tab.

Since:
9
Пакет Описание
jdk.jshell.execution
Предоставляет поддержку реализации движков выполнения JShell.
jdk.jshell.spi
Определяет интерфейс поставщика сервисов для подключаемых движков выполнения JShell.
jdk.jshell.tool
Предоставляет механизм запуска экземпляра инструмента Java Shell.
Класс Описание
DeclarationSnippet
Группа всех фрагментов объявления: объявления переменных (VarSnippet), объявления методов (MethodSnippet) и объявления типов (TypeDeclSnippet).
Diag
Диагностическая информация для фрагмента.
ErroneousSnippet
Фрагмент кода, который не является допустимым кодом языка программирования Java.
EvalException
Оборачивает исключение, брошенное клиентом выполнения.
ExpressionSnippet
Фрагмент для присваивания или выражения значения переменной.
ImportSnippet
Фрагмент для объявления импорта.
JShell
Движок состояния вычисления JShell.
JShell.Builder
Библиотека для создания экземпляров JShell.
JShellConsole
Интерфейс, предоставляющий функциональность для Console в фрагменте пользователя.
JShellException
Базовый класс для исключений, генерируемых JShell.
MethodSnippet
Фрагмент для определения метода.
PersistentSnippet
Группа фрагментов, которые сохраняются и влияют на будущий код.
Snippet
Фрагмент представляет собой фрагмент кода Java, переданный JShell.eval(java.lang.String).
Snippet.Kind
Описывает общий тип фрагмента.
Snippet.Status
Описывает текущее состояние фрагмента.
Snippet.SubKind
Подробное описание разновидности фрагмента.
SnippetEvent
Описание изменения фрагмента.
SourceCodeAnalysis
Предоставляет утилиты для анализа входных данных исходного кода.
SourceCodeAnalysis.Attribute
Атрибут раздела, который можно использовать для получения цветовой схемы.
SourceCodeAnalysis.Completeness
Описывает полноту данного ввода.
SourceCodeAnalysis.CompletionInfo
Результат analyzeCompletion(String input).
SourceCodeAnalysis.Documentation
Документация для кандидата на продолжение ввода пользователя.
SourceCodeAnalysis.Highlight
Назначает атрибуты, пригодные для окрашивания, разделам внутри фрагмента.
SourceCodeAnalysis.QualifiedNames
Список возможных полных имен.
SourceCodeAnalysis.SnippetWrapper
Оборачивание фрагмента исходного кода Java в допустимый исходный код Java верхнего уровня.
SourceCodeAnalysis.Suggestion
Кандидат на продолжение ввода пользователя.
StatementSnippet
Фрагмент для оператора.
TypeDeclSnippet
Фрагмент для определения типа (определение класса, интерфейса, перечисления или аннотированного интерфейса).
UnresolvedReferenceException
Исключение, сообщенное при попытке выполнить фрагмент RECOVERABLE_DEFINED.
VarSnippet
Фрагмент для объявления переменной.

© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://download.java.net/java/early_access/jdk24/docs/api/jdk.jshell/jdk/jshell/package-summary.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API