JShell je nová funkce v Javě 9, která usnadňuje spouštění úryvků kódu. Fragmenty kódu JShell jsou přesně stejné jako zdrojový kód Java v souboru pro aplikaci. Jak bylo uvedeno v dřívějším článku „Použití JShell v Javě 9 v NetBeans 9.0, část 3“, JShell neumožňuje několik modifikátorů – včetně výchozího, přístupového, synchronizovaného, veřejného, soukromého a chráněného – které jsou podporovány v souboru zdrojového kódu. . JShell je určen hlavně pro testování a ladění kódu Java, nikoli pro spouštění kompletních aplikací. V tomto pokračování článku spustíme úryvky pro třídy, rozhraní a pole. Použili jsme NetBeans 9 jako v předchozích článcích. Probereme také nekontrolované výjimky. Tento článek má následující sekce:
- Používání tříd
- Úprava třídy
- Výpis tříd
- Použití konstruktorů tříd
- Rozšíření třídy
- Přepsání metody
- Používání rozhraní
- Použití výchozí implementace pro metodu
- Prohlášení metody rozhraní za statickou
- Použití polí
- Používání nezaškrtnutých výjimek
- Závěr
Používání tříd
V této části probereme spouštění úryvků kódu pro třídy. Deklarujte jednoduchou třídu C následovně.
[1]-> class C { } | created class C
Třída C se vytvoří. Na rozdíl od metody, kterou lze vyvolat přímo, musí být třída nejprve vytvořena následujícím způsobem.
[3]-> new C() | $1 ==> [email protected]
Nová instance třídy C, $1 se vytvoří. Stejně jako u deklarací metod lze deklarace tříd upravit opětovnou deklarací třídy. Třída může implementovat rozhraní pomocí implements . Jako příklad deklarujte rozhraní I .
[1]-> interface I{} | created interface I
Vytvořte třídu C implementovat rozhraní I .
[3]-> class C implements I{} | replaced class C [4]->
Třída C , vytvořený dříve, bude nahrazen.
Deklarace třídy v JShell nemá koncept aplikace, jako by měla třída Java deklarovaná v souboru. Třída Java v souboru s public static void main(String[] argv) metoda je Java aplikace. public static void main(String[] argv) metoda může být přidána do JShell, ale je to jen další fragment kódu. Vytvořte třídu Ahoj která zahrnuje metodu public static void main(String[] argv) .
[1]-> class Hello{ public static void main(String[] argv){System.out.println (argv[0]+argv[1]);} } | created class Hello [2]->
main(String[]) metoda je statická metoda a je definován pro třídu spíše než pro instanci třídy. Vytvořte Řetězec[] pole dodávat do main(String[]) metoda.
String[] strArray={"Hello"," JShell"};
Vyvolejte main(String[]) metodou String[] jako argument.
Hello.main(strArray)
Výstupem je zpráva Hello JShell, jak je znázorněno na obrázku 1.
Obrázek 1: Vyvolání statické metody ve třídě
Úprava třídy
Třídu lze podle potřeby upravit úpravou nebo odstraněním kterékoli z jejích deklarací metod nebo přidáním nových metod. Znovu deklarujte třídu Ahoj bez main(String[]) a třída bude nahrazena.
[4]-> class Hello{ } | replaced class Hello [5]->
Znovu přidejte main(String[]) metoda, ale s mírně odlišným System.out.println prohlášení. Třída Dobrý den znovu bude nahrazen.
[5]-> class Hello{ public static void main(String[] argv) {System.out.println(argv[0]);} } | replaced class Hello [5]->
Vyvolejte static metoda main(String[]) pomocí Hello.main(strArray) pro jiný výstup, jak je znázorněno na obrázku 2.
Obrázek 2: Vyvolání variace metody main
Ustanovení k nahrazení třídy je užitečné při vývoji třídy. Jedna metoda může být přidána najednou a testována třída. Jako příklad přidejte druhou metodu hello(String) . Znovu, třída Ahoj bude nahrazen.
[9]-> class Hello{ void main(String[] argv){System.out.println(argv[0]);} String hello(String name){return name;} } | replaced class Hello
Metoda hello(String) přidáno, protože se jedná o metodu instance, potřebuje k vyvolání instanci třídy. Vytvořte instanci třídy.
[10]-> new Hello() | $2 ==> [email protected]
Vyvolejte metodu hello(String) pomocí instance třídy $2 .
[11]-> $2.hello("John") | $6 ==> "John"
Výpis tříd
Třída Java je typ. Typ je také rozhraní. Všechny typy definované v relaci JShell jsou uvedeny s /types příkaz. Definujte několik tříd a rozhraní.
[4]-> [1]-> class C{} | created class C [2]-> class D{} | created class D [3]-> class B{} | created class B [4]-> interface I{} | created interface I [5]-> interface J{} | created interface J
Spusťte /types a zobrazí se všechny třídy a rozhraní.
[6]-> /types | class C | class D | class B | interface I | interface J
Použití konstruktorů tříd
Třída no-arg je implicitně definována ve třídě, pokud nedefinuje žádné konstruktory s args. Předtím jsme vytvořili instanci třídy C který nedeklaroval žádné konstruktory explicitně pomocí new C() . Konstruktor no-arg může být definován explicitně.
Dále vytvořte třídu Ahoj který deklaruje konstruktor třídy. Konstruktor má jeden parametr typu String . Konstruktor může být deklarován pomocí public modifikátor a je implicitně veřejné pokud není nastaveno na public .
[6]-> class Hello{ String name; public Hello(String name){this.name=name;} void hello(){System.out.println("Hello "+name);} }
Vytvořte instanci třídy Hello .
Hello hello=new Hello("John")
Vyvolejte instanční metodu hello() pro výstup zprávy, jak je znázorněno na obrázku 3.
Obrázek 3: Použití třídy s konstruktorem
Rozšíření třídy
Třída může být rozšířena o rozšíření stejně jako v souboru zdrojového kódu Java. Jako příklad vytvořte třídu D která deklaruje název proměnné typu tt>String, konstruktor bez argumentů a metodu hello(String) . ahoj (řetězec) metoda vypíše "Ahoj" zprávu pomocí jména arg dodán.
class D{ String name="Michael"; public D(){} void hello(String name){System.out.println("Hello "+name);} }
Vytvořte třídu C který rozšiřuje třídu C a deklaruje hello() metoda, která nepřepisuje třídu D 's ahoj (String) metoda a parametry se liší. ahoj() metoda vyvolá název pole, který je zděděn z třídy D .
class C extends D{ void hello(){System.out.println("Hello "+name);} }
Okamžitá třída C a vyvolejte hello() metoda.
new C().hello()
Zobrazí se zpráva „Ahoj“, jak je znázorněno na obrázku 4. jméno hodnota pole nastavena ve třídě D se používá.
Obrázek 4: Rozšíření třídy
Pokud bychom vyvolali hello(String) metoda, která třída C dědí ze třídy D , dostali bychom jiný výstup, jak je znázorněno na obrázku 5.
Obrázek 5: Vyvolání zděděné metody z rozšířené třídy
Přepsání metody
Třída může přepsat metodu zděděnou z rozšířené třídy poskytnutím vlastní definice metody. Vytvořte třídu D který deklaruje pole name a metodu hello() .
class D{ String name="Michael"; void hello(){System.out.println("Hello "+name);} }
Deklarujte třídu C který rozšiřuje třídu D a přepíše hello() metoda. Třída C také skryje pole name .
class C extends D{ String name="John"; void hello(){System.out.println("Hello "+name); }
Vytvořte instanci třídy C a vyvolejte metodu hello() .
new C().hello()
ahoj() metoda ze třídy C se vyvolá, protože přepíše metodu z třídy D . Pole name ve třídě C skryje pole name ve třídě D . Výstup zprávy je znázorněn na obrázku 6.
Obrázek 6: Přepsání metody
Pokud třída C neskryje pole name ze třídy D , jméno pole ve třídě D jak je znázorněno na obrázku 7.
Obrázek 7: Přístup k poli z rozšířené třídy
Třída C object je instancí třídy D protože rozšiřuje třídu D . Spusťte následující příkaz a zjistěte, zda je instance třídy C je také instancí třídy D .
new C() instanceof D
Hodnota true ověřuje instanci třídy C je také instancí třídy D , jak je znázorněno na obrázku 8.
Obrázek 8: Ověření, zda je instance třídy C také instancí třídy D
Protože instance třídy C je také instancí třídy D , může být přetypován na D takto:
D d=(D)(new C());
Následně přejděte do pole name pro objekt d typu D .
d.name;
A vyvolejte metodu hello() pro objekt d typu D .
d.hello();
Výstup hodnoty pole je ze třídy D protože d je objekt typu D , jak je znázorněno na obrázku 9. Metoda hello() vyvolané je ze třídy C .
Obrázek 9: Odeslání objektu typu C do D
Používání rozhraní
V této části spustíme některé úryvky pro rozhraní v JShell. Existující třídu lze upravit tak, aby implementovala rozhraní. Vytvořte třídu C .
[1]-> class C{} | created class C
Vytvořte rozhraní I která definuje metodu hello() .
[2]-> interface I { String hello(); } | created interface I
Znovu deklarujte třídu C implementovat rozhraní I . Třída C poskytuje implementaci pro metodu hello() .
[3]-> class C implements I{ public String hello(){ return "Hello JShell"; } } | replaced class C
Vytvořte instanci třídy C .
[4]-> new C() | $1 ==> [email protected]
Pomocí proměnné instance třídy vyvolejte metodu hello() a zobrazí se výstup metody.
[5]-> $1.hello() | $2 ==> "Hello JShell" [6]->
Protože metody v rozhraní jsou implicitně veřejné zatímco metody ve třídě nejsou metodou, implementace ve třídě C musí být deklarováno veřejně modifikátor přístupu. Pokud není prohlášeno za veřejné , vypíše se chybová zpráva, protože není specifikováno public modifikátor přístupu je výchozím nastavením slabšího modifikátoru přístupu, který není při implementaci rozhraní povolen.
[3]-> class C implements I{ String hello(){ return "Hello JShell"; } } | Error: | hello() in C cannot implement hello() in I | attempting to assign weaker access privileges; was public | String hello(){ | ^--------------...
Použití výchozí implementace pro metodu
Od Java 8 může metoda rozhraní poskytovat výchozí implementaci metody pomocí klíčového slova default . Deklarujte rozhraní, které poskytuje výchozí implementaci pro metodu hello() pomocí výchozího klíčové slovo.
[1]-> interface I { default String hello(){ return "Hello JShell"; } } | created interface I
Deklarujte třídu C který implementuje rozhraní I .
[2]-> class C implements I{ } | created class C
Vytvořte instanci třídy C a vyvolejte metodu hello() . Metoda z výchozí implementace v rozhraní I získá výstup.
[3]-> new C().hello(); | $1 ==> "Hello JShell"
Prohlášení metody rozhraní za statickou
Od Java 8 mohou být metody rozhraní deklarovány jako statické . Vytvořte rozhraní I který deklaruje statický metoda.
[1]-> interface I { static String hello(){ return "Hello JShell"; } } | created interface I
Vyvolejte statickou metodu pomocí rozhraní I .
[2]-> I.hello() | $1 ==> "Hello JShell"
Třída nemůže být prohlášena za konečnou a pokud je konečná je použit modifikátor, je ignorován.
[5]-> [1]-> final class C{} | Warning: | Modifier 'final' not permitted in top-level declarations, | ignored | final class C{} | ^---^ | created class C
Použití polí
V této části spustíme některé úryvky kódu pro pole. Deklarace, vytváření instancí a přístup k polím se neliší od aplikací založených na souborech se zdrojovým kódem Java. Jako příklad deklarujte pole typu String[] . Pole je inicializováno na null .
[1]-> String[] strArray; | strArray ==> null
Přidělte paměť poli. Jakmile je velikost pole nastavena, nelze ji změnit. Prvky pole jsou inicializovány na null .
[2]-> strArray =new String[3]; | strArray ==> String[3] { null, null, null }
Inicializujte prvky pole pomocí indexů pole.
[3]-> strArray[0]="A"; strArray[1]="B"; strArray[2]="C"; | $4 ==> "A" | $5 ==> "B" | $6 ==> "C"
Zadejte délku pole a prvek na indexu 1.
[6]-> strArray.length; strArray[1]; | $9 ==> 3 | $10 ==> "B"
Délka pole je na výstupu jako 3. Prvek na indexu 1 je „B“. Pole může být inicializováno, když je deklarováno následovně.
[1]-> String[] strArray={"A","B","C"}; | strArray ==> String[3] { "A", "B", "C" }
Zadejte délku pole.
[2]-> strArray.length; | $1 ==> 3
Výstup prvku na indexu 0.
[3]-> strArray[0]; | $4 ==> "A" [4]->
Vícerozměrné pole může být deklarováno stejně jako v Java aplikaci. Vytvořte trojrozměrné pole typu String[][][] a inicializujte pole.
[1]-> String[][][] strArray={{{"A","B","C"},{"AA","AB","AC"}}, {{"B","C","A"},{"BB","BC","BA"}},{{"C","A","B"}, {"CC","CA","CB"}}}; | strArray ==> String[3][][] { String[2][] { String[3] | { "A", "B", "C" }, String[3] { "AA", ...
Zadejte délku pole.
[2]-> strArray.length; | $1 ==> 3
Zadejte délku pole na indexu 0.
[3]-> strArray[0].length; | $4 ==> 2
Výstup délky pole na indexu 1 v rámci pole na indexu 0.
[4]-> strArray[0][1].length; | $6 ==> 3
Výstup pole na indexu 0.
[5]-> strArray[0] | $10 ==> String[2][] { String[3] { "A", "B", "C" }, | String[3] { "AA", "AB", "AC" } }
Výstup pole s indexem 1 v rámci pole s indexem 0.
strArray[0][1] | $11 ==> String[3] { "AA", "AB", "AC" }
Výstup prvku s indexem 0 v poli s indexem 1 v poli s indexem 0.
strArray[0][1][0] | $12 ==> "AA" [8]->
Používání nezaškrtnutých výjimek
JShell vyvolá za běhu nekontrolované výjimky. Například proměnná typu String který byl inicializován na výchozí hodnotu null je přístupný. výjimka java.lang.NullPointerException je hozen.
[1]-> String str; | str ==> null [2]-> str.length(); | java.lang.NullPointerException thrown: | at (#2:1) [3]->
Dalším příkladem, pokud se přistupuje k indexu pole mimo velikost pole, java.lang.ArrayIndexOutOfBoundsException je hozen.
[4]-> String[] str={"A","B","C"}; | str ==> String[3] { "A", "B", "C" } [5]-> str[3]; | java.lang.ArrayIndexOutOfBoundsException thrown: 3 | at (
Pokud je vyvolána metoda, která definuje dělení nulou, java.lang.ArithmeticException je hozen.
[1]-> int average(int i,int j){ return (i+j)/0; } | created method average(int,int) [2]-> average(2,4) | java.lang.ArithmeticException thrown: / by zero | at average (#1:2) | at (#2:1) [3]->
Závěr
V těchto prvních čtyřech článcích jsme diskutovali o spouštění úryvků kódu pro proměnné, příkazy, metody, třídy, rozhraní a pole. JShell je navržen tak, aby spouštěl pouze úryvky kódu, a proto se některé funkce liší od spouštění kompletní Java aplikace ze souboru zdrojového kódu. V dalších dvou článcích prozkoumáme některé další funkce JShell.