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 ==> example@sqldat.com
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 ==> example@sqldat.com
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 ==> example@sqldat.com
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.