Пакет jdk.jshell
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
| Класс | Описание |
|---|---|
| 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, 2023, 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://docs.oracle.com/en/java/javase/21/docs/api/jdk.jshell/jdk/jshell/package-summary.html