JShell е инструмент от командния ред за стартиране на кодови фрагменти в шел среда, без да е необходимо да компилирате и стартирате цялостно приложение. JShell е нова функция в Java 9. JShell може да се използва за тестване и отстраняване на грешки в кодови фрагменти при разработване на приложение. Въвеждането на JShell трябва да бъде под формата на пълен кодов фрагмент. Въведохме JShell с две статии, „Използване на JShell в Java 9 в NetBeans 9.0, част 1“ и „Използване на JShell в Java 9 в NetBeans 9.0, част 2“, в които обсъдихме изпълнението на import оператор, деклариране и използване на променливи, сравняване на String s и работещи оператори. В тази статия-продължение ще изпълним фрагменти за Java методи. Тази статия има следните раздели:
- Настройка на средата
- Използване на методи
- Промяна на дефиниция на метод
- Претоварване на метода
- Правене на препращане към метод
- Методи за листване
- Модификаторите не са разрешени в декларациите на метод от най-високо ниво
- Заключение
Настройка на средата
Изтеглете и инсталирайте NetBeans, както беше обсъдено в по-ранна статия. Стартирайте JShell, като изберете Инструменти>Отворете обвивката на платформата Java , както е показано на фигура 1.

Фигура 1: Инструменти>Отворете обвивката на платформата на Java
Използване на методи
Метод е деклариран в JShell точно както е в Java приложение, с няколко разлики, които също са разгледани в този раздел. Като пример, декларирайте метод triple(int) което отнема int аргумент и връща int стойност.
int triple(int i) {
return i*3;
}
Изпълнете кодовия фрагмент в JShell и се създава метод.
[10]-> int triple(int i) {
return i*3;
}
| created method triple(int)
Извикайте метода triple с int стойност като arg.
triple(1)
Стойността на аргумента се утроява и се връща.
[11]-> triple(1) | $13 ==> 3 [12]->
Методът има тип на връщане и параметри, но няма модификатор на достъп като public , частен , или защитени . Това е така, защото декларацията на метод от най-високо ниво, както всички декларации от най-високо ниво, е имплицитно публична. Всеки модификатор на достъп в декларация на метод от най-високо ниво се игнорира. Всички следните декларации на метод са еквивалентни на предходната декларация на метод.
[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 показва грешки по време на компилиране, ако има такива. Като пример направете връщания тип на метода троен като String и се показва съобщение за грешка.
[10]-> String triple(int i) {
return i*3;
}
| Error:
| incompatible types: int cannot be converted to java.lang.String
| return i*3;
| ^-^
Промяна на дефиниция на метод
Изходно съобщение, което няма да бъде генерирано от приложение на Java и изброено два пъти в този раздел, е „заменен метод…“. Съобщението показва, че дефиницията на метод е променена. Разпоредбата за замяна/промяна на декларация за метод и други декларации е за улесняване на тестването.
За да модифицирате или замените метод, без да дефинирате нов метод, подписът на метода, който се задава от името на метода и параметрите на метода, включително броя на параметрите и техния тип и ред, не трябва да се променя. Като пример, декларирайте метод hello с тип връщане void и String тип параметър.
[4]-> void hello(String s){
}
| created method hello(String)
След това декларирайте същия метод hello с тип връщане String , Стринг параметър тип и израз за връщане. Предишната декларация на метод за здравей се заменя.
[5]-> String hello(String s){
return "Hello " + s;
}
| replaced method hello(String)
[6]->
Извикайте метода hello(String) и втората дефиниция на метода се извиква за извеждане на съобщение „Здравей, Джон“.
[6]-> hello("John")
| $5 ==> "Hello John"
[7]->
Аргументите на метода се обединяват при извикване на метод, ако е необходимо, както е в следния фрагмент.
[7]-> hello("John"+" & "+"Johnny")
| $22 ==> "Hello John & Johnny"
[8]->
В предишния пример за модифициране на метод заменихме връщания тип void с String . Връщането не трябва да се променя, за да се замени метод. Като пример, дефинирайте метод hello както следва.
[15]-> String hello(String str1, String str2){
return str1+str2;
}
| created method hello(String,String)
След това променете само връщането изявление. Методът hello(String,String) се заменя.
[16]-> String hello(String str1, String str2){
return "Hello"+str1+str2;
}
| replaced method hello(String,String)
Като друг пример за изпълнение на кодов фрагмент на метод, дефинирайте метод hello(String str1, String str2) с тип връщане String[] .
[17]->
String[] hello(String str1, String str2){
return new String[]{str1,str2};
}
| created method hello(String,String)
Извикайте метода с два аргумента, за да върнете масив.
[18]-> hello("John","Michael")
| $39 ==> String[2] { "John", "Michael" }
Претоварване на метод
Методът може да бъде претоварен точно както в Java приложение. Декларирайте метод hello(String s) .
[1]-> String hello(String s){
return "Hello " + s;
}
| created method hello(String)
Извикайте метода, за да изведете съобщение.
[2]-> hello("John")
| $1 ==> "Hello John"
Декларирайте различен метод hello(String,String) .
[3]-> String hello(String str1, String str2){
return str1+str2;
}
| created method hello(String,String)
Извикайте метода, за да изведете съобщение.
[5]-> hello("Hello"," John")
| $16 ==> "Hello John"
Правене на препращане към метод
JShell поддържа препращане към метод. Препратка извиква метод, който все още не е дефиниран. Декларирайте метод main(String) който прави препратка към метод hello(String) , което все още не е дефинирано. Методът main(String) се създава, но не може да бъде извикан до метода hello(String) е дефиниран.
[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
Извикване на метод main(String) и се извежда съобщение, което показва, че не може да бъде извикано.
[2]-> main("Michael")
| attempted to call method main(String) which cannot be invoked
| until method hello(java.lang.String) is declared
Декларирайте метода hello(String) който се препраща от main(String) .
[3]-> String hello(String name){
return name;
}
| created method hello(String)
Впоследствие извикайте метода main(String) отново и се извиква.
[4]-> main("Michael")
| $1 ==> "Hello Michael"
";" се добавя имплицитно, ако не се добавя в декларации на променливи от най-високо ниво и декларации на методи, които се добавят по една на ред. Но ";" не е имплицитно в изрази в рамките на метод. Като пример декларирайте следния метод и се извежда грешка.
[1]-> int average(int i,int j){
return (i+j)/2
}
| Error:
| ';' expected
Методи за листване
Методите, дефинирани в дадена сесия на JShell, са изброени с /methods команда. За да демонстрирате, дефинирайте няколко метода.
[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)
Стартирайте /methods команда и всички добавени методи ще бъдат изброени.
[5]-> /methods | printf (String,Object...)void | triple (int)int | hello (String)String | hello (String,String)String | average (int,int)int [5]->
Модификаторите не са разрешени в декларациите на метод от най-високо ниво
Докато модификаторите public , частен , и защитени в декларациите на метод от най-високо ниво се игнорират и дефиниция на метод се създава имплицитно с публичен достъп, някои други модификатори не се игнорират и не са разрешени в декларация на метод от най-високо ниво. Тези модификатори не са разрешени на най-високо ниво, тъй като те имат значение в определен контекст и не са подходящи в контекста на JShell, който е за тестване на кодови фрагменти.
Модификаторът static има значение, когато се използва с метод в контекста на клас или интерфейс, но не и на най-високо ниво. Като пример изпълнете следната декларация на метод, която включва 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)
Статичното модификаторът се игнорира, извежда се предупреждение, но методът се създава. Методът може да бъде извикан.
[2]-> hello("John")
| $1 ==> "Hello John"
[3]->
По същия начин, модификаторът final няма значение на най-горно ниво, независимо дали в декларация на метод или друга декларация, тъй като JShell е проектиран да изпълнява динамично кодови фрагменти и да декларира метод (или променлива, или клас) final ще направи фрагмента непроменен. Като пример добавете final модификатор на метод. Финал модификаторът се игнорира, генерира се предупреждение и дефиницията на метода се създава без 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)
Извикайте метода и той извежда резултат.
[3]-> triple(5) | $1 ==> 15 [4]->
Някои други модификатори също не са разрешени на най-горното ниво, независимо дали в метод или друга декларация. Докато модификаторите статични и окончателен се игнорират и се създава дефиниция на метод, модификатори абстрактни и роден в метод от най-високо ниво генерира грешка и методът не се създава.
[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){
| ^----^
Модификатори по подразбиране и синхронизирани в декларация на метод от най-високо ниво или всяка друга декларация също не са разрешени и генерират грешка.
Заключение
В тази статия обсъдихме пускането на кодови фрагменти за Java методи в JShell. В следваща статия ще обсъдим стартирането на кодови фрагменти за Java класове, интерфейси и масиви.