JShell er en ny funktion i Java 9 for at gøre det lettere at køre kodestykker. JShell-kodestykker er præcis det samme som Java-kildekode i en fil til en applikation. Som diskuteret i en tidligere artikel, "Brug af JShell i Java 9 i NetBeans 9.0, del 3", tillader JShell ikke flere modifikatorer – inklusive standard, adgang, synkroniseret, offentlig, privat og beskyttet – der understøttes i en kildekodefil . JShell er primært designet til at teste og fejlfinde Java-kode og ikke til at køre komplette applikationer. I denne fortsættelsesartikel skal vi køre uddrag for klasser, grænseflader og arrays. Vi har brugt NetBeans 9 som i de tidligere artikler. Vi vil også diskutere ukontrollerede undtagelser. Denne artikel har følgende sektioner:
- Brug af klasser
- Ændring af en klasse
- Angivelse af klasser
- Brug af klassekonstruktører
- Udvidelse af en klasse
- Tilsidesættelse af en metode
- Brug af grænseflader
- Brug af en standardimplementering til en metode
- Erklæring af en grænseflademetode for at være statisk
- Brug af arrays
- Brug af umarkerede undtagelser
- Konklusion
Brug af klasser
I dette afsnit vil vi diskutere kørende kodestykker for klasser. Erklær en simpel klasse C som følger.
[1]-> class C { } | created class C
Klasse C bliver skabt. I modsætning til en metode, der kan påberåbes direkte, skal en klasse først instansieres som følger.
[3]-> new C() | $1 ==> [email protected]
En ny forekomst af klasse C, $1 bliver skabt. Som med metodeerklæringer kan klasseerklæringer modificeres ved at generklære klassen. En klasse kan implementere en grænseflade ved hjælp af implementer . Som et eksempel, erklære en grænseflade I .
[1]-> interface I{} | created interface I
Opret klasse C at implementere interface I .
[3]-> class C implements I{} | replaced class C [4]->
Klasse C , oprettet tidligere, bliver erstattet.
En klasseerklæring i JShell har ikke konceptet som en applikation, som en Java-klasse, der er erklæret i en fil, ville have. En Java-klasse i en fil med public static void main(String[] argv) metoden er en Java-applikation. Den offentlige statiske void main(String[] argv) metode kan tilføjes i JShell, men er blot endnu et kodestykke. Opret en klasse Hej der inkluderer metoden 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]->
hoved(streng[]) metode er en statisk metode og er defineret for klassen i stedet for en forekomst af en klasse. Opret en streng[] array til at levere til main(String[]) metode.
String[] strArray={"Hello"," JShell"};
Kald main(String[]) metode med strengen[] som et argument.
Hello.main(strArray)
En Hello JShell-meddelelse udlæses, som vist i figur 1.
Figur 1: Påberåber statisk metode i en klasse
Ændring af en klasse
En klasse kan ændres efter behov ved at ændre eller slette en hvilken som helst af dens metodeerklæringer eller tilføje nye metoder. Generklær klassen Hej uden main(String[]) metoden, og klassen bliver erstattet.
[4]-> class Hello{ } | replaced class Hello [5]->
Gentilføj main(String[]) metode, men med en lidt anden System.out.println udmelding. Klasse Hej igen bliver erstattet.
[5]-> class Hello{ public static void main(String[] argv) {System.out.println(argv[0]);} } | replaced class Hello [5]->
Kald den statiske metode main(String[]) med Hello.main(strArray) for et andet output, som vist i figur 2.
Figur 2: Påberåber en variation af metode hoved
Bestemmelsen om at erstatte en klasse er nyttig ved udvikling af en klasse. Der kan tilføjes én metode ad gangen, og klassen testes. Som et eksempel kan du tilføje en anden metode hello(String) . Igen, klasse Hej bliver erstattet.
[9]-> class Hello{ void main(String[] argv){System.out.println(argv[0]);} String hello(String name){return name;} } | replaced class Hello
Metoden hello(String) tilføjet, da det er en instansmetode, vil det kræve en klasseinstans at påkalde. Opret en klasseinstans.
[10]-> new Hello() | $2 ==> [email protected]
Kald metode hello(String) ved hjælp af klasseforekomst $2 .
[11]-> $2.hello("John") | $6 ==> "John"
Angivelse af klasser
En Java-klasse er en type. En grænseflade er også en type. Alle typer defineret i JShell-sessionen er listet med /types kommando. Definer nogle få klasser og grænseflader.
[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
Kør /types kommando, og alle klasser og grænseflader bliver vist.
[6]-> /types | class C | class D | class B | interface I | interface J
Brug af klassekonstruktører
No-arg-klassen er implicit defineret i en klasse, hvis den ikke definerer nogen konstruktører med args. Vi havde tidligere instansieret en klasse C der ikke erklærede nogen konstruktører eksplicit med nye C() . no-arg-konstruktøren kan defineres eksplicit.
Opret derefter en klasse Hej der erklærer en klassekonstruktør. Konstruktøren har én parameter af typen String . Konstruktøren kan erklæres for offentligheden modifikator og er implicit offentlig hvis ikke indstillet til offentlig .
[6]-> class Hello{ String name; public Hello(String name){this.name=name;} void hello(){System.out.println("Hello "+name);} }
Opret en forekomst af klassen Hej .
Hello hello=new Hello("John")
Kald instansmetoden hello() for at udsende en meddelelse, som vist i figur 3.
Figur 3: Brug af en klasse med en konstruktør
Udvidelse af en klasse
En klasse kan udvides med extensions ligesom i en Java-kildekodefil. Som et eksempel, opret klasse D der erklærer et variabelnavn af typen tt>String, en no-arg-konstruktør og en metode hello(String) . hej(streng) metode udsender et "Hej" besked med navnet arg leveret.
class D{ String name="Michael"; public D(){} void hello(String name){System.out.println("Hello "+name);} }
Opret en klasse C der udvider klasse C og erklærer hello() metode, som ikke tilsidesætter klasse D 's hej(streng) metode og parametre er forskellige. hello() metode kalder et feltnavn, som er nedarvet fra klassen D .
class C extends D{ void hello(){System.out.println("Hello "+name);} }
Instantiér klasse C og påkald hello() metode.
new C().hello()
En "Hej"-meddelelse udsendes, som vist i figur 4. navnet feltværdi sat i klasse D bruges.
Figur 4: Forlængelse af en klasse
Hvis vi påkaldte hello(String) metode, der klassen C arver fra klasse D , ville vi få et andet output, som vist i figur 5.
Figur 5: Påkaldelse af en nedarvet metode fra en udvidet klasse
Tilsidesættelse af en metode
En klasse kan tilsidesætte en metode, der er nedarvet fra en udvidet klasse, ved at give sin egen metodedefinition. Opret en klasse D der erklærer et felt navn og en metode hello() .
class D{ String name="Michael"; void hello(){System.out.println("Hello "+name);} }
Erklær en klasse C der udvider klasse D og tilsidesætter hello() metode. Klasse C skjuler også feltet navn .
class C extends D{ String name="John"; void hello(){System.out.println("Hello "+name); }
Opret en forekomst af klassen C og påkald metoden hello() .
new C().hello()
hello() metode fra klasse C bliver påkaldt, fordi den tilsidesætter metoden fra klassen D . Feltet navn i klasse C skjuler feltet navn i klasse D . Meddelelsesoutputtet er vist i figur 6.
Figur 6: Tilsidesættelse af en metode
Hvis klasse C skjuler ikke feltet navn fra klasse D , navnet felt i klasse D bruges, som vist i figur 7.
Figur 7: Adgang til felt fra udvidet klasse
En klasse C objekt er en forekomst af klasse D fordi det udvider klasse D . Kør følgende sætning for at finde om en forekomst af klassen C er også en forekomst af klasse D .
new C() instanceof D
En værdi på sand verificerer en forekomst af klasse C er også en forekomst af klasse D , som vist i figur 8.
Figur 8: Bekræftelse af, om en forekomst af klasse C også er en forekomst af klasse D
Fordi en forekomst af klassen C er også en forekomst af klasse D , kan den castes til D som følger:
D d=(D)(new C());
Efterfølgende, adgangsfeltet navn for objekt d af typen D .
d.name;
Og påkald metoden hello() for objekt d af typen D .
d.hello();
Feltværdioutputtet er fra klasse D fordi d er et objekt af typen D , som vist i figur 9. Metoden hello() påkaldt er fra klasse C .
Figur 9: Casting af et objekt af type C til D
Brug af grænseflader
I dette afsnit skal vi køre nogle uddrag til grænseflader i JShell. En eksisterende klasse kunne modificeres for at implementere en grænseflade. Opret klasse C .
[1]-> class C{} | created class C
Opret en grænseflade I der definerer en metode hello() .
[2]-> interface I { String hello(); } | created interface I
Generklær klasse C at implementere interface I . Klasse C leverer implementering af metoden hello() .
[3]-> class C implements I{ public String hello(){ return "Hello JShell"; } } | replaced class C
Opret en forekomst af klassen C .
[4]-> new C() | $1 ==> [email protected]
Ved at bruge klasseinstansvariablen, start metoden hello() og metodeoutputtet bliver vist.
[5]-> $1.hello() | $2 ==> "Hello JShell" [6]->
Fordi metoder i en grænseflade implicit er offentlige mens metoder i en klasse ikke er en metode, implementering i klasse C skal erklæres for offentligheden adgangsmodifikator. Hvis ikke erklæret offentlig , udsendes en fejlmeddelelse, fordi den ikke angiver en offentlig adgangsmodifikator er som standard en svagere adgangsmodifikator, hvilket ikke er tilladt ved implementering af en grænseflade.
[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(){ | ^--------------...
Brug af en standardimplementering til en metode
Fra Java 8 kan en grænseflademetode give en standardimplementering for en metode ved at bruge nøgleordet default . Erklære en grænseflade, der giver en standardimplementering for metoden hello() ved at bruge standard søgeord.
[1]-> interface I { default String hello(){ return "Hello JShell"; } } | created interface I
Erklær en klasse C der implementerer grænsefladen I .
[2]-> class C implements I{ } | created class C
Opret en forekomst af klassen C og påkald metoden hello() . Metoden fra standardimplementeringen i grænsefladen I får output.
[3]-> new C().hello(); | $1 ==> "Hello JShell"
Erklæring af en grænseflademetode for at være statisk
Siden Java 8 kan grænseflademetoder blive erklæret statiske . Opret en grænseflade I der erklærer en statisk metode.
[1]-> interface I { static String hello(){ return "Hello JShell"; } } | created interface I
Start den statiske metode ved at bruge grænsefladen I .
[2]-> I.hello() | $1 ==> "Hello JShell"
En klasse kan ikke erklæres endelig, og hvis den er final modifikator bruges, ignoreres den.
[5]-> [1]-> final class C{} | Warning: | Modifier 'final' not permitted in top-level declarations, | ignored | final class C{} | ^---^ | created class C
Brug af arrays
I dette afsnit skal vi køre nogle kodestykker for arrays. Erklæring, instansiering og adgang til arrays er ikke anderledes end i et Java-kildekodefilbaseret program. Som et eksempel kan du deklarere en matrix af typen String[] . Array initialiseres til null .
[1]-> String[] strArray; | strArray ==> null
Tildel hukommelse til arrayet. Arraystørrelsen kan ikke ændres, når den først er indstillet. Array-elementer initialiseres til null .
[2]-> strArray =new String[3]; | strArray ==> String[3] { null, null, null }
Initialiser array-elementerne ved hjælp af array-indeksene.
[3]-> strArray[0]="A"; strArray[1]="B"; strArray[2]="C"; | $4 ==> "A" | $5 ==> "B" | $6 ==> "C"
Udskriv array-længden og elementet ved indeks 1.
[6]-> strArray.length; strArray[1]; | $9 ==> 3 | $10 ==> "B"
Arraylængden udlæses som 3. Element ved indeks 1 er "B". Et array kan initialiseres, når det erklæres som følger.
[1]-> String[] strArray={"A","B","C"}; | strArray ==> String[3] { "A", "B", "C" }
Udskriv array-længden.
[2]-> strArray.length; | $1 ==> 3
Udskriv elementet ved indeks 0.
[3]-> strArray[0]; | $4 ==> "A" [4]->
Et multidimensionelt array kan erklæres ligesom i en Java-applikation. Opret et tredimensionelt array af typen String[][][][] og initialiser arrayet.
[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", ...
Udskriv array-længden.
[2]-> strArray.length; | $1 ==> 3
Udskriv længden af array ved indeks 0.
[3]-> strArray[0].length; | $4 ==> 2
Udskriv længden af array ved indeks 1 i array ved indeks 0.
[4]-> strArray[0][1].length; | $6 ==> 3
Udskriv arrayet ved indeks 0.
[5]-> strArray[0] | $10 ==> String[2][] { String[3] { "A", "B", "C" }, | String[3] { "AA", "AB", "AC" } }
Udskriv arrayet ved indeks 1 i array ved indeks 0.
strArray[0][1] | $11 ==> String[3] { "AA", "AB", "AC" }
Udskriv elementet ved indeks 0 i array ved indeks 1 i array ved indeks 0.
strArray[0][1][0] | $12 ==> "AA" [8]->
Brug af umarkerede undtagelser
JShell kaster umarkerede undtagelser under kørsel. Som et eksempel, hvis en variabel af typen String der er blevet initialiseret til standardværdien null er tilgået. java.lang.NullPointerException er smidt.
[1]-> String str; | str ==> null [2]-> str.length(); | java.lang.NullPointerException thrown: | at (#2:1) [3]->
Som et andet eksempel, hvis der tilgås et array-indeks uden for en arrays størrelse, java.lang.ArrayIndexOutOfBoundsException er smidt.
[4]-> String[] str={"A","B","C"}; | str ==> String[3] { "A", "B", "C" } [5]-> str[3]; | java.lang.ArrayIndexOutOfBoundsException thrown: 3 | at (
Hvis en metode, der definerer division med nul, påberåbes, java.lang.ArithmeticException er smidt.
[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]->
Konklusion
I disse første fire artikler diskuterede vi at køre kodestykker for variabler, udsagn, metoder, klasser, grænseflader og arrays. JShell er designet til kun at køre kodestykker, og som sådan er nogle af funktionerne anderledes, end når man kører et komplet Java-program fra en kildekodefil. I yderligere to artikler skal vi udforske nogle andre funktioner i JShell.