JShell è uno strumento da riga di comando per eseguire frammenti di codice in un ambiente shell senza dover compilare ed eseguire un'applicazione completa. JShell è una nuova funzionalità di Java 9. JShell può essere utilizzato per testare ed eseguire il debug di frammenti di codice durante lo sviluppo di un'applicazione. L'input di JShell dovrebbe essere sotto forma di un frammento di codice completo. Abbiamo introdotto JShell con due articoli, "Utilizzo di JShell in Java 9 in NetBeans 9.0, parte 1" e "Utilizzo di JShell in Java 9 in NetBeans 9.0, parte 2", in cui abbiamo discusso dell'esecuzione di import dichiarazione, dichiarando e utilizzando variabili, confrontando String s e istruzioni in esecuzione. In questo articolo di continuazione, eseguiremo snippet per i metodi Java. Questo articolo ha le seguenti sezioni:
- Impostazione dell'ambiente
- Utilizzo dei metodi
- Modifica di una definizione di metodo
- Sovraccarico del metodo
- Fare un riferimento diretto a un metodo
- Metodi di elenco
- Modificatori non consentiti nelle dichiarazioni di metodo di primo livello
- Conclusione
Impostazione dell'ambiente
Scarica e installa NetBeans, come discusso in un articolo precedente. Avvia JShell selezionando Strumenti>Apri Java Platform Shell , come mostrato nella Figura 1.
Figura 1: Strumenti>Apri Java Platform Shell
Utilizzo dei metodi
Un metodo è dichiarato in JShell proprio come in un'applicazione Java, con alcune differenze, anch'esse discusse in questa sezione. Ad esempio, dichiara un metodo triple(int) che richiede un int argomento e restituisce un int valore.
int triple(int i) { return i*3; }
Esegui il frammento di codice in JShell e viene creato un metodo.
[10]-> int triple(int i) { return i*3; } | created method triple(int)
Richiama il metodo triplo con un int valore come arg.
triple(1)
Il valore dell'argomento viene triplicato e restituito.
[11]-> triple(1) | $13 ==> 3 [12]->
Il metodo ha un tipo restituito e parametri ma nessun modificatore di accesso come pubblico , privato o protetto . È perché una dichiarazione di metodo di primo livello, come tutte le dichiarazioni di primo livello, è implicitamente pubblica. Qualsiasi modificatore di accesso in una dichiarazione di metodo di primo livello viene ignorato. Tutte le seguenti dichiarazioni di metodo sono equivalenti alla precedente dichiarazione di metodo.
[1]-> private int triple(int i){ return 3*i; } | created method triple(int) [2]-> protected int triple(int i){ return 3*1; } | replaced method triple(int) [3]-> public int triple(int i){ return 3*i; } | replaced method triple(int) [4]->
JShell visualizza eventuali errori in fase di compilazione. Ad esempio, rendere il tipo restituito del metodo triplo come Stringa e viene visualizzato un messaggio di errore.
[10]-> String triple(int i) { return i*3; } | Error: | incompatible types: int cannot be converted to java.lang.String | return i*3; | ^-^
Modifica di una definizione di metodo
Un messaggio di output che non verrebbe generato da un'applicazione Java ed elencato già due volte in questa sezione è “metodo sostituito…”. Il messaggio indica che una definizione di metodo è stata modificata. La disposizione per sostituire/modificare una dichiarazione di metodo e altre dichiarazioni serve a facilitare il test.
Per modificare o sostituire un metodo senza definire un nuovo metodo, la firma del metodo, che è impostata dal nome del metodo e dai parametri del metodo, inclusi il numero di parametri e il loro tipo e ordine, non deve essere modificata. Ad esempio, dichiara un metodo ciao con tipo restituito void e una Stringa tipo parametro.
[4]-> void hello(String s){ } | created method hello(String)
Quindi, dichiara lo stesso metodo ciao con tipo restituito Stringa , una Stringa type parametro e un'istruzione return. La precedente dichiarazione del metodo per ciao viene sostituito.
[5]-> String hello(String s){ return "Hello " + s; } | replaced method hello(String) [6]->
Richiama il metodo hello(String) e la seconda definizione del metodo viene invocata per generare un messaggio "Hello John".
[6]-> hello("John") | $5 ==> "Hello John" [7]->
Gli argomenti del metodo vengono concatenati nella chiamata al metodo, se necessario, come nel frammento di codice seguente.
[7]-> hello("John"+" & "+"Johnny") | $22 ==> "Hello John & Johnny" [8]->
Nell'esempio precedente di modifica di un metodo, abbiamo sostituito il tipo restituito void con Stringa . Il ritorno non deve essere modificato per sostituire un metodo. Ad esempio, definisci un metodo ciao come segue.
[15]-> String hello(String str1, String str2){ return str1+str2; } | created method hello(String,String)
Successivamente, modifica solo il ritorno dichiarazione. Il metodo ciao(Stringa,Stringa) viene sostituito.
[16]-> String hello(String str1, String str2){ return "Hello"+str1+str2; } | replaced method hello(String,String)
Come altro esempio di esecuzione di un frammento di codice di metodo, definire un metodo hello(String str1, String str2) con tipo restituito Stringa[] .
[17]-> String[] hello(String str1, String str2){ return new String[]{str1,str2}; } | created method hello(String,String)
Richiama il metodo con due argomenti per restituire un array.
[18]-> hello("John","Michael") | $39 ==> String[2] { "John", "Michael" }
Sovraccarico del metodo
Un metodo può essere sovraccaricato proprio come in un'applicazione Java. Dichiara un metodo hello(String s) .
[1]-> String hello(String s){ return "Hello " + s; } | created method hello(String)
Richiama il metodo per generare un messaggio.
[2]-> hello("John") | $1 ==> "Hello John"
Dichiara un metodo diverso hello(String,String) .
[3]-> String hello(String str1, String str2){ return str1+str2; } | created method hello(String,String)
Richiama il metodo per generare un messaggio.
[5]-> hello("Hello"," John") | $16 ==> "Hello John"
Fare un riferimento diretto a un metodo
JShell supporta la creazione di riferimenti in avanti a un metodo. Un riferimento diretto richiama un metodo che non è stato ancora definito. Dichiara un metodo main(String) che fa riferimento a un metodo hello(String) , che non è stato ancora definito. Il metodo main(String) viene creato ma non può essere invocato fino al metodo hello(String) è definito.
[1]-> String main(String str){ return "Hello "+hello(str); } | created method main(String), however, it cannot be invoked until | method hello(java.lang.String) is declared
Richiama il metodo main(String) e viene visualizzato un messaggio, indicando che non può essere invocato.
[2]-> main("Michael") | attempted to call method main(String) which cannot be invoked | until method hello(java.lang.String) is declared
Dichiara il metodo hello(String) a cui fa riferimento main(String) .
[3]-> String hello(String name){ return name; } | created method hello(String)
Successivamente, richiama il metodo main(String) di nuovo e viene invocato.
[4]-> main("Michael") | $1 ==> "Hello Michael"
Il ";" viene aggiunto implicitamente se non viene aggiunto nelle dichiarazioni di variabili di primo livello e nelle dichiarazioni di metodo che vengono aggiunte una per riga. Ma il ";" non è implicito nelle istruzioni all'interno di un metodo. Ad esempio, dichiara il seguente metodo e viene visualizzato un errore.
[1]-> int average(int i,int j){ return (i+j)/2 } | Error: | ';' expected
Metodi di elenco
I metodi definiti in una determinata sessione di JShell sono elencati con /methods comando. Per dimostrare, definisci alcuni metodi.
[1]-> int triple(int i) { return i*3; } | created method triple(int) [2]-> String hello(String s){ return "Hello" + s; } | created method hello(String) [3]-> String hello(String str1, String str2){ return str1+str2; } | created method hello(String,String) [4]-> int average(int i,int j){ return (i+j)/0; } | created method average(int,int)
Esegui /methods comando e tutti i metodi aggiunti vengono elencati.
[5]-> /methods | printf (String,Object...)void | triple (int)int | hello (String)String | hello (String,String)String | average (int,int)int [5]->
Modificatori non consentiti nelle dichiarazioni di metodo di primo livello
Considerando che i modificatori pubblici , privato e protetto nelle dichiarazioni di metodo di primo livello vengono ignorate e viene creata una definizione di metodo implicitamente con accesso pubblico, alcuni altri modificatori non vengono ignorati e non sono consentiti in una dichiarazione di metodo di primo livello. Questi modificatori non sono consentiti al livello più alto perché hanno un significato all'interno di un determinato contesto e non sono adatti nel contesto di JShell, che consiste nel testare frammenti di codice.
Il modificatore statico ha significato se usato con un metodo nel contesto di una classe o di un'interfaccia, ma non al livello più alto. Ad esempio, esegui la seguente dichiarazione di metodo che include static .
[1]-> static String hello(String name){ return "Hello "+name; } | Warning: | Modifier 'static' not permitted in top-level declarations, | ignored | static String hello(String name){ | ^----^ | created method hello(String)
Il statico modificatore viene ignorato, viene emesso un avviso, ma viene creato un metodo. Il metodo può essere invocato.
[2]-> hello("John") | $1 ==> "Hello John" [3]->
Allo stesso modo, il modificatore final non ha significato al livello più alto, sia in una dichiarazione di metodo che in qualsiasi altra dichiarazione, perché JShell è progettato per eseguire frammenti di codice in modo dinamico e dichiarare un metodo (o una variabile o una classe) final renderebbe lo snippet immodificabile. Ad esempio, aggiungi il finale modificatore di un metodo. La finale modificatore viene ignorato, viene generato un avviso e viene creata la definizione del metodo senza il final .
[2]-> final int triple(int i){ return 3*i; } | Warning: | Modifier 'final' not permitted in top-level declarations, | ignored | final int triple(int i){ | ^---^ | created method triple(int)
Richiama il metodo e genera un risultato.
[3]-> triple(5) | $1 ==> 15 [4]->
Anche alcuni altri modificatori non sono consentiti al livello superiore, sia in un metodo che in qualsiasi altra dichiarazione. Considerando che i modificatori statici e finale vengono ignorati e viene creata una definizione di metodo, i modificatori abstract e nativo in un metodo di primo livello genera un errore e un metodo non viene creato.
[1]-> abstract String hello(String s){ return "Hello "+s; } | Error: | Modifier 'abstract' not permitted in top-level declarations | abstract String hello(String s){ | ^------^ [1]-> [1]-> native String hello(String s){ return "Hello "+s; } | Error: | Modifier 'native' not permitted in top-level declarations | native String hello(String s){ | ^----^
Modificatori predefiniti e sincronizzato in una dichiarazione di metodo di primo livello o in qualsiasi altra dichiarazione non sono consentiti e generano un errore.
Conclusione
In questo articolo, abbiamo discusso dell'esecuzione di frammenti di codice per i metodi Java in JShell. In un articolo successivo, discuteremo dell'esecuzione di frammenti di codice per classi, interfacce e array Java.