Spec-Zone.ru › OpenJDK 27

Пакет 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.

Начиная с:
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.CompletionContext
Различные флаги, описывающие контекст, в котором выполняется автодополнение.
SourceCodeAnalysis.CompletionInfo
Результат analyzeCompletion(String input).
SourceCodeAnalysis.CompletionState
Предоставляет доступ к состоянию автодополнения.
SourceCodeAnalysis.Documentation
Документация для кандидата на продолжение введённых пользователем данных.
SourceCodeAnalysis.ElementSuggestion
Описание Element, который может быть продолжением заданного фрагмента.
SourceCodeAnalysis.ElementSuggestionConvertor<S>
Преобразователь списка SourceCodeAnalysis.ElementSuggestion в список пользовательских целевых элементов автодополнения.
SourceCodeAnalysis.Highlight
Назначает диапазонам внутри фрагмента атрибуты, используемые для раскрашивания.
SourceCodeAnalysis.QualifiedNames
Список возможных полных имён.
SourceCodeAnalysis.SnippetWrapper
Обёртка, преобразующая фрагмент исходного кода Java в допустимый исходный код верхнего уровня Java.
SourceCodeAnalysis.Suggestion
Кандидат на продолжение введённых пользователем данных.
StatementSnippet
Фрагмент для оператора.
TypeDeclSnippet
Фрагмент для определения типа (определения класса, интерфейса, перечисления или интерфейса аннотаций).
UnresolvedReferenceException
Исключение, возникающее при попытке выполнить фрагмент RECOVERABLE_DEFINED.
VarSnippet
Фрагмент для определения переменной.

Сообщить об ошибке или предложить улучшение
Дополнительную справочную информацию по API и документацию для разработчиков см. в разделе Документация Java SE, содержащем более подробные описания для разработчиков, обзор концепций, определения терминов, обходные решения и примеры работающего кода. Другие версии.
Java является товарным знаком или зарегистрированным товарным знаком Oracle и/или её аффилированных лиц в США и других странах.
Авторское право © 1993, 2026, Oracle и/или её аффилированные лица, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
Все права защищены. Использование регулируется условиями лицензии и политикой распространения документации.

© 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.

Spec-Zone.ru

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