Tutorial de JShell
Introducción
¿Qué es JShell?
JShell es una herramienta de línea de comandos que facilita la programación exploratoria al permitir el uso interactivo de los elementos del lenguaje de programación Java. JShell es un REPL (Lectura-Evaluación-Impresión-Bucle). Es ideal tanto para aprender Java como para explorar código desconocido (incluyendo nuevas API de Java). El desarrollo típico en Java implica escribir un programa completo, compilarlo (corregir errores), ejecutarlo, identificar errores, editarlo y repetirlo. Con JShell, se pueden introducir elementos del programa uno a uno, ver el resultado al instante y realizar los ajustes necesarios. Durante el desarrollo, se puede pegar código en JShell o copiar código de trabajo desde JShell a un editor de programas.
Iniciando JShell
Primero instale JDK . JShell está incluido en JDK . Para iniciar la herramienta JShell, simplemente escriba jshell
en la línea de comandos:
% jshell
A lo largo de este tutorial, bold fixed-width font
se utilizará para indicar el texto que escribe a medida que sigue la lectura.
Si ingresó a la herramienta JShell, escriba /exit
para salir:
% jshell | Welcome to JShell -- Version 9 | For an introduction type: /help intro jshell> /exit | Goodbye
En este tutorial, todos los ejemplos usan el modo detallado. Para que lo que veas coincida, te recomiendo seguirlo en modo detallado. Una vez que te familiarices, probablemente querrás ejecutarlo en modo normal o más conciso. Para iniciar JShell en modo detallado, escribe:
% jshell -v
Fragmentos
Probándolo
JShell acepta sentencias Java, definiciones de variables, métodos y clases, importaciones y expresiones. Me referiré a estos fragmentos de código Java como fragmentos . Por ejemplo, puedes introducir una sentencia en el prompt; se aplicarán los efectos secundarios y se mostrará la salida:
jshell> System.out.println("Hi"); Hi jshell>
De forma predeterminada, JShell le proporcionará información sobre lo ingresado. Aquí se define una variable:
jshell> int x = 45 x ==> 45 | created variable x : int
Primero, se muestra el resultado, que se puede leer: la variable x tiene el valor 45. Dado que estamos en modo detallado, también hay una descripción de lo ocurrido; los mensajes informativos comienzan con una barra vertical. Nota: Se muestran tanto el nombre como el tipo de la variable creada.
Tenga en cuenta que los puntos y coma finales se agregarán automáticamente al final de su fragmento si faltan.
Cuando se ingresa una expresión que no tiene una variable nombrada, se crea una variable scratch para que se pueda hacer referencia al valor más adelante:
jshell> 2 + 2 $3 ==> 4 | created scratch variable $3 : int jshell> String twice(String s) { ...> return s + s; ...> } | created method twice(String) jshell> twice("Ocean") $5 ==> "OceanOcean" | created scratch variable $5 : String
Cambio de definiciones
Para cambiar la definición de una variable, método o clase previamente ingresada, simplemente introduzca una nueva definición. Por ejemplo, el método que definimos anteriormente puede obtener una nueva definición:
jshell> String twice(String s) { ...> return "Twice:" + s; ...> } | modified method twice(String) jshell> twice("thing") $7 ==> "Twice:thing" | created scratch variable $7 : String
Tenga en cuenta que en lugar de decir " created method
", como antes, dice " modified method
"; esto significa que se cambió la definición, pero tiene la misma firma y, por lo tanto, todos los usos existentes continúan siendo válidos.
También puedes cambiar las definiciones de maneras incompatibles. Por ejemplo:
jshell> String x x ==> null | replaced variable x : String | update overwrote variable x : int
Hemos cambiado el tipo de la variable x; observe que ahora dice " replaced
". Hablaremos más sobre esto más adelante.
Iniciamos JShell en el modo de retroalimentación verbosa, por lo que es bastante conciso. Puedes configurar la cantidad y el formato de la salida con el /set feedback
comando, por ejemplo /set feedback concise
. Si planeas usar JShell principalmente pegando desde otras ventanas, te recomendamos usar un modo de retroalimentación sin solicitud de ayuda y solo con retroalimentación de errores /set feedback silent
:
Referencia futura
Dado que uno de los objetivos de JShell es facilitar la programación exploratoria (y dado que algunas formas de programación lo requieren), permite definir métodos cuyos cuerpos hacen referencia a métodos, variables o clases aún no definidos. Supongamos que desea definir un método para el volumen de una esfera; puede introducir la fórmula:
jshell> double volume(double radius) { ...> return 4.0 / 3.0 * PI * cube(radius); ...> } | created method volume(double), however, it cannot be invoked until variable PI, and method cube(double) are declared
JShell permite la definición, pero advierte sobre lo que aún queda por definir. Se puede hacer referencia a la definición, pero si se intenta ejecutarla, fallará.
jshell> double PI = 3.1415926535 PI ==> 3.1415926535 | created variable PI : double jshell> volume(2) | attempted to call method volume(double) which cannot be invoked until method cube(double) is declared jshell> double cube(double x) { return x * x * x; } | created method cube(double) | update modified method volume(double) jshell> volume(2) $5 ==> 33.510321637333334 | created scratch variable $5 : double
Con todas las definiciones en su lugar, el volumen ahora funciona.
Usaré este código para ilustrar mejor el reemplazo incompatible. Supongamos que no está satisfecho con la precisión de PI:
jshell> BigDecimal PI = new BigDecimal("3.141592653589793238462643383") PI ==> 3.141592653589793238462643383 | replaced variable PI : BigDecimal | update modified method volume(double) which cannot be invoked until this error is corrected: | bad operand types for binary operator '*' | first type: double | second type: java.math.BigDecimal | return 4.0 / 3.0 * PI * cube(radius); | ^------------^ | update overwrote variable PI : double
La nueva definición de PI es de tipo incompatible con la definición de volume(). Dado que estamos en modo detallado, se muestra información de actualización para otras definiciones afectadas por el cambio; aquí se describe la incompatibilidad. Tenga en cuenta que el modo detallado es el único modo de retroalimentación integrado que mostrará información de actualización. En otros modos de retroalimentación, no se mostrará ninguna advertencia hasta que se ejecute el código; esto es para evitar ráfagas de actualizaciones innecesarias. En todos los casos, al ejecutar el método volume() se mostrará el problema:
jshell> volume(2) | attempted to call method volume(double) which cannot be invoked until this error is corrected: | bad operand types for binary operator '*' | first type: double | second type: java.math.BigDecimal | return 4.0 / 3.0 * PI * cube(radius); | ^------------^
Excepciones
En un seguimiento de excepciones, una ubicación dentro del código introducido en REPL se muestra como #id/linenumber, donde id del fragmento es el número mostrado en /list y line-number es el número de línea dentro del fragmento. A continuación, la excepción ocurre en el fragmento n.° 1 (divide()) en la segunda línea de divide:
jshell> int divide(int x, int y) { ...> return x / y; ...> } | created method divide(int,int) jshell> divide(5, 0) | java.lang.ArithmeticException thrown: / by zero | at divide (#1:2) | at (#2:1) jshell> /list 1 : int divide(int x, int y) { return x / y; } 2 : divide(5, 0)
Completar tabulaciones - Fragmentos
Pulse la tecla de tabulación para completar la entrada actual. Por ejemplo:
jshell> vol
<tab>
Será reemplazado por:
jshell> volume(
Si hay más de una finalización, se enumerará el conjunto de finalizaciones:
jshell> System.c
<tab>class clearProperty( console() currentTimeMillis() jshell> System.c
Se agregarán todos los caracteres comunes y el cursor se colocará al final de la entrada, para que se puedan agregar más.
Cuando esté en el paréntesis de apertura de una llamada de método, la pestaña mostrará las finalizaciones como se indica arriba (si hay algo interesante para mostrar) y mostrará los tipos de parámetros:
jshell> "hello".startsWith(
<tab>Signatures: boolean String.startsWith(String prefix, int toffset) boolean String.startsWith(String prefix) <press tab again to see documentation> jshell> "hello".startsWith(
Al presionar la tecla Tab nuevamente se mostrará una versión de texto simple de la documentación del primer método.
jshell> "hello".startsWith(
<tab>boolean String.startsWith(String prefix, int toffset) Tests if the substring of this string beginning at the specified index starts with the specified prefix. Parameters: prefix - the prefix. toffset - where to begin looking in this string. Returns: true if the character sequence represented by the argument is a prefix of the substring of this object starting at index toffset ; false otherwise. The result is false if toffset is negative or greater than the length of this String object; otherwise the result is the same as the result of the expression this.substring(toffset).startsWith(prefix) <press tab to see next documentation> jshell> "hello".startsWith(
Transformación de fragmentos
Al ingresar un identificador que necesita ser importado, presione <shift-tab> i (es decir, mantenga presionada la tecla shift mientras presiona tab, luego suelte y presione i) y aparecerá un menú que le permitirá agregar automáticamente la importación:
jshell> new JFrame
<mayúsculas-tabulador>i 0: Do nothing 1: import: javax.swing.JFrame Choice: 1 Imported: javax.swing.JFrame jshell> new JFrame
Nota: puede haber más de una opción de importación.
Después de ingresar una expresión, puede convertirla en una declaración de variable con <shift-tab> v. Es decir, la expresión se convertirá en el inicializador de la declaración de variable y el tipo de la variable será el tipo de la expresión:
jshell> new JFrame("Demo")
<mayúsculas-tabulador>v jshell> JFrame | = new JFrame("Demo")
El cursor se posicionará donde debe ir el nombre de la variable. Escriba el nombre de la variable y presione Enter.
Nota: La expresión debe ser válida; de lo contrario, se ignorará la solicitud de transformación. Por lo tanto, se requirió la importación de JFrame antes de la transformación de la variable.
A veces, el tipo de resultado de la expresión no se ha importado. En ese caso, <shift-tab> v ofrecerá importar y crear la variable. Continuamos, desde arriba, introduciendo el nombre de la variable 'frame' y pulsando Intro:
jshell> JFrame frame = new JFrame("Demo") frame ==> javax.swing.JFrame[frame0,0,0,0x0,invalid,hidden, ... tPaneCheckingEnabled=true] | created variable frame : JFrame jshell> frame.setSize(300, 200) jshell> frame.setVisible(true) jshell> frame.getGraphics()
<mayúsculas-tabulador>v 0: Do nothing 1: Create variable 2: import: java.awt.Graphics. Create variable Choice: 2 Imported: java.awt.Graphics jshell> Graphics | = frame.getGraphics()
Se debe ingresar el nombre de la variable de contexto gráfico.
Comandos
Comandos - Introducción
JShell cuenta con varios comandos para controlar el entorno y mostrar información. Se distinguen de los fragmentos de código por una barra diagonal inicial. Puede obtener información sobre las variables, métodos y tipos actuales con los comandos /vars, /methods y /types. Puede obtener una lista de los fragmentos de código introducidos con el comando /list. Por ejemplo:
jshell> /vars | int x = 45 | int $3 = 4 | String $5 = "OceanOcean" jshell> /methods | twice (String)String jshell> /list 1 : System.out.println("Hi"); 2 : int x = 45; 3 : 2 + 2 4 : String twice(String s) { return s + s; } 5 : twice("Ocean")
Observará que se muestran los tipos y valores de las variables y la firma de tipo de los métodos.
JShell tiene entradas de inicio que se ejecutan de forma silenciosa y automática antes de que se inicie, para que pueda empezar a trabajar rápidamente. Estas no aparecen a menos que las solicite con /list -start
o /list -all
:
jshell> /list -all s1 : import java.util.*; s2 : import java.io.*; s3 : import java.math.*; s4 : import java.net.*; s5 : import java.util.concurrent.*; s6 : import java.util.prefs.*; s7 : import java.util.regex.*; 1 : System.out.println("Hi"); 2 : int x = 45; 3 : 2 + 2 4 : String twice(String s) { return s + s; } 5 : twice("Ocean")
Las entradas de inicio predeterminadas son varias importaciones comunes. Puede personalizarlas con el /set start
comando ``;`. Para obtener más información, escriba ``/help/set start``. Este /save -start
comando es útil si desea crear su archivo como una variante del inicio predeterminado.
Utilice /help para obtener una lista de comandos.
Otros comandos importantes incluyen /exit
salir de JShell, /save
guardar los fragmentos y /open
volver a leerlos.
Completar tabulaciones - Comandos
La función de completar tabulaciones también funciona para comandos y argumentos de comandos:
jshell> /
<tab>/! /? /drop /edit /env /exit /help /history /imports /list /methods /open /reload /reset /save /set /types /vars <press tab again to see synopsis> jshell> /
Las finalizaciones únicas se realizan in situ:
jshell> /l
<tab>
se reemplaza con:
jshell> /list
La función de completar tabulaciones funciona para las opciones de comando:
jshell> /list -
<tab>-all -history -start <press tab again to see synopsis> jshell> /list -
Tenga en cuenta que otra pestaña mostrará la sinopsis del comando, que es una breve descripción del comando. Al volver a la pestaña, se mostrará la documentación de /help:
jshell> /list -
<tab> <tab> <tab>list the source you have typed <press tab again to see full documentation> jshell> /list -
Show the source of snippets, prefaced with the snippet id. /list List the currently active snippets of code that you typed or read with /open /list -start List the automatically evaluated start-up snippets /list -all List all snippets including failed, overwritten, dropped, and start-up /list <name> List snippets with the specified name (preference for active snippets) /list <id> List the snippet with the specified snippet id jshell> /list -
Las finalizaciones de argumentos únicos se realizan en el lugar:
jshell> /list -a
<tab>
se reemplaza con:
jshell> /list -all
Los nombres de los fragmentos también se pueden completar con tabulaciones:
jshell> /ed v
<tab>
se reemplaza con:
jshell> /ed volume
El uso de la pestaña en la posición del argumento de archivo del comando muestra los archivos disponibles:
jshell> /open
<tab>myfile1 myfile2 definitions.jsh <press tab again to see synopsis> jshell> /open
La finalización de nombres de archivos únicos se realiza en el lugar:
jshell> /open d
<tab>is replaced with: jshell> /open definitions.jsh
Abreviatura de comando
Los comandos, /set
subcomandos, argumentos de comando y opciones de comando se pueden abreviar, siempre que sean únicos.
Dado que, /list
es el único comando que comienza con /l
y la única /list
opción de comando que comienza con -a
es -all
:
jshell> /list -all
se puede abreviar:
jshell> /l -a
Y, /set
es el único comando que comienza con /se
, el único /set
subcomando que comienza con fe
es feedback
, y, a menos que se agreguen modos de usuario, verbose
es el único modo de retroalimentación que comienza con v
. el comando:
jshell> /set feedback verbose
se puede abreviar:
jshell> /se fe v
Tenga en cuenta que /s
no es suficiente, ya que /save
tiene el mismo comienzo. En caso de duda, puede usar la función de tabulación.
Editores
Para editar más fácilmente entradas pasadas, particularmente aquellas de muchas líneas, puede invocar un editor en el fragmento proporcionando su nombre o id (número en /lista):
jshell> /edit volume
O bien, para todos los fragmentos y para introducir nuevos, /edit
sin argumentos. Al guardar en el editor, se introducirá cualquier fragmento modificado o nuevo. Verá la información de los fragmentos en la ventana de JShell; sin embargo, no aparecerá ningún mensaje de JShell y no podrá introducir comandos ni fragmentos en la ventana de JShell hasta que se cierre el editor.
Si no especifica un editor, se proporcionará un editor integrado simple. Indique el editor que se invocará con el /set editor
comando. El argumento del comando es el editor externo que desea utilizar. Este editor debe abrir su propia ventana. Por ejemplo:
jshell> /set editor kwrite | Editor set to: kwrite jshell> /edit ...
El usuario define x en la ventana del editor externo y selecciona guardar
| created variable x of type int with initial value 6
El usuario cierra el editor externo
jshell>
Edición de shell
Navegación
La edición de entrada de usuario se basa en JLine2, que es funcionalmente similar a BSD editline y GNU readline en modo Emacs. Permite editar la línea actual o acceder al historial completo, remontándose a varias sesiones de uso de la herramienta jshell.
En este tutorial se utilizará "Ctrl-x" para significar mantener presionada la tecla Control y luego presionar la tecla x; y "Meta-x" para significar mantener presionada la tecla Meta (a menudo la tecla Alt izquierda) y luego presionar la tecla x.
La navegación básica dentro de una línea utiliza las teclas de flecha derecha/izquierda o, alternativamente, Ctrl+b y Ctrl+f (para avanzar y retroceder). La navegación entre líneas en el historial utiliza las teclas de flecha arriba/abajo. Por lo tanto, al pulsar la flecha arriba una vez, se reemplaza la línea actual con el comando o fragmento anterior. Al pulsar la flecha arriba de nuevo, se accede a la línea anterior. El historial contiene tanto comandos como fragmentos; tenga en cuenta que los fragmentos pueden tener varias líneas; las flechas arriba/abajo le permiten navegar por las líneas individuales de un fragmento.
Llave | Acción |
---|---|
Devolver | Introduzca la línea actual |
Flecha izquierda | Retroceder un carácter |
Flecha derecha | Avanzar un caracter |
Flecha hacia arriba | Moverse una línea hacia arriba (hacia atrás en el historial) |
Flecha hacia abajo | Moverse hacia abajo una línea (avanzar a través del historial) |
Ctrl-a | Moverse al principio de la línea |
Ctrl-e | Moverse hasta el final de la línea |
Meta-b | Retroceder una palabra |
Meta-f | Avanzar una palabra |
Navegación histórica
JShell mantiene un historial de fragmentos y comandos. Puede navegar por este historial para volver a ingresar o editar entradas anteriores con las flechas arriba/abajo/izquierda/derecha. El texto ingresado se insertará. La tecla Supr permite eliminar texto. Presione la tecla Enter para aceptar la línea del historial de nuevo (modificada o no).
Puedes mover un fragmento a la vez usando Control arriba y Control abajo (es decir, manteniendo presionada la tecla Control mientras presionas la tecla arriba o abajo).
Por ejemplo:
jshell> class C { ...> int x; ...> } | created class C jshell> /list 1 : class C { int x; } jshell>
<flecha hacia arriba>
La tecla de flecha hacia arriba hará que la línea muestre:
jshell> /list
Al presionar la flecha hacia arriba nuevamente se mostrará:
jshell> }
La última línea de la definición de la clase. Al presionar la flecha hacia abajo se regresa al /list
comando y al presionar Enter se ejecuta:
jshell> /list 1 : class C { int x; }
Ctrl+flecha arriba subirá fragmentos. Por lo tanto, para fragmentos de una sola línea, Ctrl+flecha arriba funciona como una flecha arriba. Pero, para fragmentos de varias líneas, como la clase C, subirá la parte superior del fragmento.
Modificando
Se puede agregar texto en la posición actual del cursor simplemente escribiéndolo. La tecla Supr eliminará un carácter a la derecha del cursor, y la tecla Retroceso eliminará a la izquierda.
Llave | Acción |
---|---|
Borrar | Eliminar el carácter debajo del cursor |
Retroceso | Eliminar el carácter antes del cursor |
Ctrl-k | Matar (eliminar) el texto desde el cursor hasta el final de la línea |
Meta-d | Matar desde el cursor hasta el final de la palabra |
Ctrl-w | Matar desde el cursor hasta el espacio en blanco anterior |
Ctrl-y | Pegue el texto eliminado más recientemente en la línea |
Meta-y | Después de Ctrl+y, presione para recorrer el texto eliminado anteriormente |
Buscar y más
Buscar en el historial es una herramienta potente. Presione Ctrl+r seguido de la cadena que desee buscar en su historial. La búsqueda se realizará hacia atrás, comenzando por las entradas más recientes e incluyendo sesiones anteriores de la herramienta jshell. Siguiendo el ejemplo anterior, al presionar Ctrl+r en el mensaje:
jshell>
<Ctrl-r>
reemplazará el mensaje con:
(reverse-i-search)`':
Al escribir "clase" la pantalla cambiará a:
(reverse-i-search)`class': class C {
Se muestra la línea más reciente con el texto "class". La búsqueda es incremental, por lo que esta línea se recupera solo con el primer carácter "c". Puede continuar buscando en el historial presionando Ctrl+r repetidamente. Ctrl+s retrocederá la búsqueda hasta el momento actual.
Puede definir una macro de teclado usando Ctrl+x seguido de un paréntesis de apertura "Ctrl+x (), luego ingrese el texto y finalmente escriba "Ctrl+x)". Cuando desee usar su macro, escriba "Ctrl+x e".
Llave | Acción |
---|---|
Ctrl-r | Buscar hacia atrás en la historia |
Ctrl-s | Buscar hacia adelante a través de la historia |
Ctrl-x ( | Comenzar a ingresar macros |
Ctrl-x ) | Finalizar macro |
Ctrl-x e | Usar macro |
Para obtener más información, consulte la información de usuario de JLine2 y la documentación de GNU Readline .
Trabajar con código externo
Establecer una ruta de clase
Una forma de conectar código externo al que la herramienta jshell puede acceder es configurando la ruta de clases. Esta ruta se puede configurar en la línea de comandos:
% jshell --class-path myOwnClassPath
La ruta de clases debe apuntar a los directorios o archivos JAR con los paquetes a los que desea acceder. El código debe compilarse en archivos de clase. No se puede acceder al código del paquete predeterminado (también conocido como paquete sin nombre) desde JShell. Una vez establecida la ruta de clases, se pueden importar estos paquetes:
jshell> import my.cool.code.*
También utiliza el comando '/env' para establecer la ruta de clase:
jshell> /env --class-path myOwnClassPath | Setting new options and restoring state.
Tenga en cuenta que este comando restablece el estado de ejecución y vuelve a cargar cualquier fragmento actual con la nueva configuración de classpath (u otra configuración del entorno).
Configuración de las opciones del módulo
De manera similar, se puede configurar la ruta del módulo, especificar módulos adicionales para resolver y proporcionar exportaciones de módulos, ya sea en la línea de comandos de la herramienta jshell o en las opciones de /env:
% jshell --module-path myOwnModulePath --add-modules my.module
Para ver la configuración del entorno actual, utilice '/env' sin argumentos:
jshell> /env | --add-modules my.module | --module-path myOwnModulePath | --class-path myOwnClassPath
Para más detalles véase:
jshell> /help context
Modos de retroalimentación
Configuración de un modo de retroalimentación
Un modo de retroalimentación es una configuración de interacción del usuario con nombre. Existen modos integrados y el usuario puede crear modos personalizados. Estos modos no se pueden modificar, pero se puede crear una copia como base de un modo definido por el usuario. Existen cuatro modos integrados, en orden descendente de nivel de detalle: detallado, normal, conciso y silencioso. Esta tabla muestra las diferencias:
Modo | Fragmentos de valor | Declaración | Actualizaciones | Comandos | Inmediato |
---|---|---|---|---|---|
verboso | nombre ==> valor (y descripción) | Sí | Sí | Sí | \njshell> |
normal | nombre ==> valor | Sí | No | Sí | \njshell> |
conciso | nombre ==> valor (solo expresiones) | No | No | No | jshell> |
silencioso | No | No | No | No | -> |
Donde "Fragmentos de valor" indica lo que se muestra para los fragmentos que tienen valor, como expresiones, asignaciones y declaraciones de variables; "Declaración" indica si hay comentarios para las declaraciones de métodos, clases, enumeraciones, interfaces e interfaces de anotación; "Actualizaciones" indica si se muestran cambios que no sean el fragmento actual; y "Comandos" indica si los comandos brindan comentarios que indican éxito.
A menos que se configure mediante una bandera de línea de comandos o el /set feedback
comando, el modo de retroalimentación será "normal". El /set feedback
comando establece el modo de retroalimentación:
jshell> /set feedback verbose | Feedback mode: verbose jshell> 2 + 2 $1 ==> 4 | created scratch variable $1 : int jshell> /set feedback silent -> 2 + 2 -> /set feedback normal | Feedback mode: normal jshell> 2 + 2 $3 ==> 4 jshell> /set feedback concise jshell> 2 + 2 $4 ==> 4 jshell>
Tenga en cuenta que, al configurarlo como "normal" o "verbose", la respuesta del comando le avisa de que ha sucedido, pero "concise" y "silent" no. Observe también las tres formas diferentes de respuesta a la expresión (incluida ninguna para "silence").
Para ver los modos de retroalimentación actuales y disponibles, use el /set feedback
comando sin argumentos. Tenga en cuenta que el modo actual se muestra como el comando que lo establecería:
jshell> /set feedback | /set feedback verbose | | Available feedback modes: | concise | normal | silent | verbose
Definición de un modo de retroalimentación
Hay tres configuraciones para cada modo: las indicaciones, el truncamiento y el formato. Supongamos que desea cambiar la indicación. Los modos integrados no se pueden modificar, pero puede crear fácilmente una copia de un modo existente; este es el primer paso:
jshell> /set mode mine normal -command | Created new feedback mode: mine
El nuevo modo "mío" es una copia del modo "normal". La -command
opción indica que desea recibir comentarios de comandos (la columna "Comandos" de la tabla anterior). Si, en su modo, no desea que los comandos describan la acción realizada (por ejemplo, "| Nuevo modo de comentarios creado: mío" arriba), utilice -quiet
en lugar de -command
.
Al igual que todos /set
los comandos, al utilizar el /set prompt
comando sin configurar argumentos se obtendrá la configuración actual:
jshell> /set prompt normal | /set prompt normal "\njshell> " " ...> "
La primera cadena es el mensaje de aviso normal, la segunda es el mensaje de continuación, que se utiliza si el fragmento ocupa varias líneas. Aquí configuramos los mensajes de aviso, cambiamos al nuevo modo para verlo y probarlo:
jshell> /set prompt mine "\nmy mode: " ".......: " jshell> /set feedback mine | Feedback mode: mine my mode: class C { .......: int x; .......: } | created class C my mode:
Las cadenas de solicitud pueden contener '%s' que se sustituirá con el siguiente ID de fragmento: tenga en cuenta que es posible que lo que el usuario ingrese en la solicitud no tenga asignado ese ID; por ejemplo, puede ser un error o un comando.
Todas las configuraciones tienen una duración equivalente a la sesión actual de la herramienta (nota: no se restablecen con /reset
). Si desea que sean las predeterminadas en futuras sesiones, utilice la -retain
opción para conservarlas:
my mode: /set mode mine -retain my mode: /set feedback mine -retain | Feedback mode: mine my mode: /exit | Goodbye % jshell | Welcome to JShell -- Version 9 | For an introduction type: /help intro my mode:
Al mostrar valores, si son demasiado largos, se truncan. El /set truncation
comando determina qué es "demasiado largo". Sin ajustes, se mostrará el ajuste actual, heredado del modo normal:
my mode: /set truncation mine | /set truncation mine 80 | /set truncation mine 1000 expression,varvalue my mode: String big = IntStream.range(0,1200).mapToObj(n -> "" + (char) ('a' + n % 26)).collect(Collectors.joining()) big ==> "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv ... fghijklmnopqrstuvwxyzabcd"
Los tipos de selector que aparecen opcionalmente después de la longitud de truncamiento seleccionan las condiciones bajo las cuales se aplicará dicha configuración. En este caso, el selector de mayúsculas y minúsculas indica el tipo de fragmento cuyo valor se muestra. Consulte /help /set truncation
los detalles sobre los selectores. La configuración mostrada anteriormente significa que los valores se truncarán a 80 caracteres, a menos que el valor sea el valor de una expresión (el expression
selector de mayúsculas y minúsculas) o el valor de una variable, como se solicita explícitamente al introducir solo el nombre de la variable (el varvalue
selector de mayúsculas y minúsculas). El orden es importante; el último prevalece. Si se hubiera invertido el orden, todos los truncamientos serían de 80 caracteres.
Digamos que, en nuestro modo, queremos que el truncamiento predeterminado sea 100 y solo queremos valores largos si se solicitan explícitamente.
my mode: /set truncation mine 100 my mode: /set truncation mine 300 varvalue my mode: big + big $2 ==> "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi ... yzabcdefghijklmnopqrstuvwxyzabcd" my mode: big big ==> "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu vwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl ... jklmnopq rstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd" my mode: /set mode mine -retain
Nota: si estos cambios son los deseados, es necesario conservar los cambios en el modo.
Ahora cambiemos la salida del fragmento según nuestras preferencias.
my mode: import java.beans.* my mode: Locale.CANADA.getUnicodeLocaleAttributes() $5 ==> []
En el formato heredado del modo normal, una importación no proporciona información y no se muestra el tipo de valor. El formato de la salida del fragmento se configura con el /set format
comando. Pruebe esto, sin configuración, para algún modo, para ver la configuración de formato actual:
my mode: /set format mine
Hay mucha ayuda sobre este comando con /help /set format
. Léala ahora y consúltela a medida que avanzamos. La información principal que se muestra está determinada por el display
campo. Se pueden definir otros campos para facilitar la definición del display
campo. Los modos predefinidos (no silenciosos) definen varios, como se puede ver en la salida del comando anterior. Estos se heredan en nuestro modo de ejemplo. A continuación, se muestran las definiciones de visualización para la importación:
my mode: /set format mine display "{pre}added import {name}{post}" import-added my mode: /set format mine display "{pre}re-added import {name}{post}" import-modified,replaced
El name
campo está predefinido como el nombre del fragmento.
my mode: import java.beans.* | re-added import java.beans.*
Los campos pre
"y post
" contienen los caracteres de prefijo y sufijo para cada línea de retroalimentación. Supongamos que no nos gusta el prefijo de barra vertical:
my mode: /set format mine pre "" my mode: void m() {} created method m() my mode: import java.beans.* re-added import java.beans.* my mode: /set feedback mine Feedback mode: mine
Nota: esto afecta a todos los comentarios, incluidos los comentarios de comando.
Para mostrar el tipo al mostrar valores, será más fácil cambiar el result
campo definido por los modos predefinidos:
my mode: /set format mine result "{type} {name} = {value}{post}" added,modified,replaced-primary-ok my mode: Locale.CANADA.getUnicodeLocaleAttributes() Set<String> $11 = [] my mode: 2 + 2 int $12 = 4
Queremos result
que no esté vacío solo cuando sea nuevo/actualizado ( added,modified,replaced
), esté en el fragmento ingresado ( primary
) y no tenga errores ( ok
).
Para eliminar permanentemente un modo retenido:
my mode: /set feedback verbose -retain | Feedback mode: verbose jshell> /set mode mine -delete -retain
Guiones
Scripts de JShell
Un script JShell es una secuencia de fragmentos y comandos JShell, uno por línea, en un archivo.
Se puede crear un script externamente en un editor o generarlo con uno de estos comandos:
jshell> /save mysnippets.jsh jshell> /save -history myhistory.jsh jshell> /save -start mystartup.jsh
Estos, respectivamente, guardan en el archivo de script especificado los fragmentos activos actuales, el historial de todos los fragmentos y comandos (válidos e inválidos) o el contenido de la configuración del script de inicio actual.
Los nombres de los scripts pueden ser un nombre de archivo del sistema operativo (como el anterior) o uno de estos scripts predefinidos:
Guion | Contenido |
---|---|
POR DEFECTO | El inicio predeterminado, si no se configura ninguno, incluye declaraciones de importación comúnmente necesarias |
IMPRESIÓN | Define métodos JShell que redirigen a los métodos print , println y printf enPrintStream |
JAVANÉS | Importa todos los paquetes de Java SE, esto es grande y causará un retraso de inicio notable |
Cargando scripts
Los scripts se pueden cargar enumerándolos en la línea de comandos de la herramienta jshell:
% jshell mysnippets.jsh
o en el /open
comando:
jshell> /open PRINTING
Scripts de inicio
Los scripts de inicio se cargan cada vez que se reinicia la herramienta jshell; el reinicio se produce durante el inicio inicial y con los comandos de reinicio ( /reset
, /reload
y /env
). A menos que el usuario lo configure, DEFAULT
se utiliza el script de inicio predeterminado ( ), que define las declaraciones de importación comunes. Nota: El lenguaje Java define que el paquete java.lang se importa automáticamente, por lo que no es necesario importarlo explícitamente.
Para configurar el script de inicio utilice /set start
:
jshell> /set start mystartup.jsh jshell> /reset | Resetting state.
Como con todos /set
los comandos, la duración de la configuración corresponde a la sesión actual, a menos que -retain
se use la bandera. Usarla sin la -retain
bandera, como se indicó anteriormente, generalmente solo es útil para probar de forma segura la configuración de un script de inicio. Una vez encontrada la configuración deseada, se puede conservar con:
jshell> /set start -retain
Luego, el script de inicio establecido se cargará en la próxima invocación de la herramienta jshell.
Remember that the startup scripts are only loaded into the current session when the state is reset. Note: it is the contents of a file that is stored, rather than a reference to the file. The file is only read at the time the /set start
command is run. Contrastingly, when predefined script names are used, they are by reference and may be updated with new releases of the JDK.
The startup script may alternatively be specified with the --startup
command-line flag (note, command-line flags can be abbreviated, if unique):
% jshell --start mystartup.jsh
Early development versions of JShell defined a printf
JShell method, this has been removed from the default startup to assure cut-and-paste compatibility with Java programs. However, it is very handy for experimentation to have print methods that don't need System.out.
prefixing them. You can specify more than one startup script on /set start
:
jshell> /set start -retain DEFAULT PRINTING jshell> /exit | Goodbye % jshell | Welcome to JShell -- Version 9 | For an introduction type: /help intro jshell> println("Hello World!") Hello World!
This sets the startup to load both the default imports and printing definitions. The -retain
flag is used to set these as the startup scripts of future sessions of the jshell tool. Try the /set start
, without arguments, to see the details of the startup this defines.
To set more than one startup script on the command-line, use the --startup
flag for each script:
% jshell --start DEFAULT --start PRINTING
https://docs.oracle.com/en/java/javase/24/jshell/introduction-jshell.html