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 класове, интерфейси и масиви.