Syntaxe Java - Java syntax
![]() | Tento článek obsahuje seznam obecných Reference, ale zůstává z velké části neověřený, protože postrádá dostatečné odpovídající vložené citace.Leden 2014) (Zjistěte, jak a kdy odstranit tuto zprávu šablony) ( |

The syntax z Jáva odkazuje na soubor pravidel definování způsobu psaní a interpretace programu Java.
Syntaxe je většinou odvozena od C a C ++. Na rozdíl od C ++ neexistují v Javě žádné globální funkce ani proměnné, ale existují datové členy, které jsou také považovány za globální proměnné. Veškerý kód patří třídy a všechny hodnoty jsou předměty. Jedinou výjimkou je primitivní typy, které nejsou z důvodu výkonu reprezentovány instancí třídy (lze je však automaticky převést na objekty a naopak pomocí autoboxing ). Některé funkce jako přetížení operátora nebo celé číslo bez znaménka typy jsou vynechány, aby se zjednodušil jazyk a zabránilo se možným programovacím chybám.
Syntaxe Java byla postupně rozšiřována v průběhu mnoha hlavních JDK zprávy, a nyní podporuje funkce jako generické programování a funkční literály (nazývané výrazy lambda v Javě). Od roku 2017 vychází nová verze JDK dvakrát ročně, přičemž každé vydání přináší postupná vylepšení jazyka.
Základy
Identifikátor
An identifikátor je název prvku v souboru kód. Existují určité standardy konvence pojmenování při výběru názvů prvků. Identifikátory v Javě jsou citlivý na velká písmena.
Identifikátor může obsahovat:
- Libovolný znak Unicode, který je písmenem (včetně číselných písmen jako římské číslice ) nebo číslice.
- Znamení měny (například ¥).
- Spojovací interpunkční znak (např _ ).
Identifikátor nemůže:
- Začněte číslicí.
- Být rovno vyhrazenému klíčovému slovu, literálu null nebo boolean literálu.
Klíčová slova
abstraktní | pokračovat | pro | Nový | přepínač |
tvrdit | výchozí | jít do | balík | synchronizované |
booleovský | dělat | -li | soukromé | tento |
přestávka | dvojnásobek | nářadí | chráněný | házet |
byte | jiný | import | veřejnost | hodí |
případ | výčet | instanceof | vrátit se | přechodný |
chytit | rozšiřuje | int | krátký | Snaž se |
char | finále | rozhraní | statický | var |
třída | Konečně | dlouho | strictfp | prázdnota |
konst | plovák | rodák | super | nestálý |
zatímco |
Literály
Celá čísla | |
---|---|
binární (představeno v prostředí Java SE 7) | 0b11110101 (0b následuje binární číslo) |
osmičkový | 0365 (0 následované osmičkovým číslem) |
hexadecimální | 0xF5 (0x následované šestnáctkovým číslem) |
desetinný | 245 (desetinné číslo) |
Plovoucí bod hodnoty | |
plovák | 23.5F, .5f, 1,72E3F (desetinný zlomek s volitelným ukazatelem exponentu, za nímž následuje F) |
0x.5FP0F, 0x.5P-6f (0x následuje hexadecimální zlomek s povinným ukazatelem exponentu a příponou F) | |
dvojnásobek | 23.5D, .5, 1,72E3D (desetinný zlomek s volitelným indikátorem exponentu, následovaný volitelným D) |
0x.5FP0, 0x.5P-6D (0x následuje hexadecimální zlomek s povinným ukazatelem exponentu a volitelnou příponou D) | |
Znakové literály | |
char | 'A', „Z“, „ u0231“ (znak nebo znak unikající, uzavřený v jednoduchých uvozovkách) |
Booleovské literály | |
booleovský | skutečný, Nepravdivé |
null doslovný | |
nulový odkaz | nula |
Řetězcové literály | |
Tětiva | "Ahoj světe" (sled znaků a úniků znaků uzavřený do uvozovek) |
Znaky unikají v řetězcích | |
Unicode charakter | u3876 ( u následovaný hexadecimálním bodem kódu Unicode až do U + FFFF) |
Osmičkový uniknout | \352 (osmičkové číslo nepřesahující 377, předchází zpětné lomítko) |
Posuv řádku | n |
Návrat vozíku | r |
Krmivo pro formuláře | F |
Obrácené lomítko | \\ |
Jednoduchá nabídka | \' |
Dvojitá nabídka | \" |
Tab | t |
Backspace | b |
Celočíselné literály jsou int
ve výchozím nastavení zadejte dlouho
typ je určen připojením L
nebo l
přípona k doslovnému, např. 367L
. Od verze Java SE 7 je možné mezi číslice čísla zahrnout podtržítka, aby se zvýšila čitelnost; například číslo 145608987 lze psát jako 145_608_987.
Proměnné
Proměnné jsou identifikátory spojené s hodnotami. Jsou deklarovány zápisem typu a názvu proměnné a jsou volitelně inicializovány ve stejném příkazu přiřazením hodnoty.
int počet; // Deklarace neinicializované proměnné s názvem 'count', typu 'int'počet = 35; // Inicializace proměnnéint počet = 35; // Deklarování a inicializace proměnné současně
Více proměnných stejného typu lze deklarovat a inicializovat v jednom příkazu pomocí čárky jako oddělovače.
int A, b; // Deklarace více proměnných stejného typuint A = 2, b = 3; // Deklarace a inicializace více proměnných stejného typu
Od verze Java 10 je možné automaticky odvodit typy proměnných pomocí var
.
// stream bude mít typ FileOutputStream, jak je odvozeno od jeho inicializátoruvar proud = Nový FileOutputStream("file.txt");// Ekvivalentní deklarace s explicitním typemFileOutputStream proud = Nový FileOutputStream("file.txt");
Bloky kódu
Oddělovače { a } označte blok kódu a nový rozsah. Členové třídy a tělo metody jsou příklady toho, co může uvnitř těchto závorek žít v různých kontextech.
Uvnitř těl metod lze složené závorky použít k vytvoření nových oborů, a to následovně:
prázdnota dělej něco() { int A; { int b; A = 1; } A = 2; b = 3; // Neplatné, protože proměnná b je deklarována ve vnitřním rozsahu.}
Komentáře
Java má tři druhy komentářů: tradiční komentáře, komentáře na konci řádku a komentáře k dokumentaci.
Tradiční komentáře, známé také jako blokové komentáře, začínají na /*
a končí s */
, mohou se rozprostírat na více řádcích. Tento typ komentáře byl odvozen z C a C ++.
/ * Toto je víceřádkový komentář.Může zabírat více než jeden řádek. * /
Poznámky na konci řádku začínají na //
a prodloužit se na konec aktuálního řádku. Tento typ komentáře je také přítomen v C ++ a v moderní C.
// Toto je komentář na konci řádku
Komentáře k dokumentaci ve zdrojových souborech zpracovává Javadoc nástroj pro generování dokumentace. Tento typ komentáře je totožný s tradičními komentáři, kromě toho, že začíná na /**
a dodržuje konvence definované nástrojem Javadoc. Technicky jsou tyto komentáře zvláštním druhem tradičního komentáře a nejsou specificky definovány ve specifikaci jazyka.
/** * Toto je komentář k dokumentaci. * * @autor John Doe */
Univerzální typy
Třídy v balíčku java.lang jsou implicitně importovány do každého programu, pokud žádné explicitně importované typy nemají stejné názvy. Mezi důležité patří:
- java.lang.Object
- Java špičkový typ. Nadtřída všech tříd, které nedeklarují nadřazenou třídu. Na tento typ lze převést všechny hodnoty, i když u primitivních hodnot to zahrnuje autoboxing.
- řetězec java.lang
- Základní typ řetězce Java. Neměnný. Některé metody zacházejí s každým UTF-16 kódová jednotka jako „znak“, ale metody převodu na
int []
to je efektivně UTF-32 jsou také k dispozici. - java.lang. Hoditelné
- supertyp všeho, co může být hozen nebo chycen s Java
házet
achytit
prohlášení.
Struktura programu
Java aplikace se skládají ze sbírek tříd. Třídy existují v balíčcích, ale lze je také vnořit do jiných tříd.
hlavní
metoda
Každá aplikace Java musí mít vstupní bod. To platí jak pro aplikace grafického rozhraní, tak pro konzolové aplikace. Vstupním bodem je hlavní
metoda. Může existovat více než jedna třída s a hlavní
metoda, ale hlavní třída je vždy definována externě (například v a soubor manifestu ). Metoda musí být statický
a jsou předávány argumenty příkazového řádku jako pole řetězců. Na rozdíl od C ++ nebo C#, nikdy nevrací hodnotu a musí se vrátit prázdnota
.
veřejnost statický prázdnota hlavní(Tětiva[] args) {}
Balíčky
Balíčky jsou součástí názvu třídy a slouží ke seskupení a / nebo rozlišení pojmenovaných entit od ostatních. Dalším účelem balíčků je řídit přístup k kódu společně s modifikátory přístupu. Například, java.io.InputStream
je plně kvalifikovaný název třídy pro třídu InputStream
který se nachází v balíčku java.io
.
Balíček je deklarován na začátku souboru s balík
prohlášení:
balík myapplication.mylibrary;veřejnost třída Moje třída {}
Třídy s veřejnost
modifikátor musí být umístěn v souborech se stejným názvem a Jáva příponu a vložte do vnořených složek odpovídajících názvu balíčku. Výše uvedená třída myapplication.mylibrary.MyClass
bude mít následující cestu: myapplication / mylibrary / MyClass.java
.
Dovozní prohlášení
Zadejte dovozní prohlášení
Deklarace importu typu umožňuje, aby se na pojmenovaný typ odkazovalo spíše jednoduchým názvem než celým názvem, který obsahuje balíček. Importní prohlášení mohou být prohlášení o dovozu jednoho typu nebo prohlášení o dovozu na vyžádání. Deklarace importu musí být umístěna v horní části souboru kódu po deklaraci balíčku.
balík můj balíček;import java.util.Random; // Deklarace jednoho typuveřejnost třída ImportsTest { veřejnost statický prázdnota hlavní(Tětiva[] args) { / * Následující řádek odpovídá * java.util.Random random = nová java.util.Random (); * Bez importu by to bylo nesprávné. */ Náhodný náhodný = Nový Náhodný(); }}
Deklarace o importu na vyžádání jsou uvedena v kódu. „Import typu“ importuje všechny typy balíčku. „Statický import“ importuje členy balíčku.
import java.util. *; / * Tato forma importu tříd vytvoří všechny třídy v balíčku java.util k dispozici podle názvu, lze použít místo dovozní prohlášení v předchozím příkladu. * /import Jáva.*; / * Toto prohlášení je legální, ale od té doby nic nedělá nejsou žádné třídy přímo v balíčku java. Všechny jsou v balíčcích v rámci balíčku java. Tím se neimportují všechny dostupné třídy. * /
Statické dovozní prohlášení
Tento typ prohlášení je k dispozici od J2SE 5.0. Statický import deklarace umožňují přístup ke statickým členům definovaným v jiné třídě, rozhraní, anotaci nebo výčtu; bez zadání názvu třídy:
import statické java.lang.System.out; // 'out' je statické pole v java.lang.Systemveřejnost třída Ahoj světe { veřejnost statický prázdnota hlavní(Tětiva[] args) { / * Následující řádek odpovídá: System.out.println („Ahoj světe!“); a bez dovozního prohlášení by byly nesprávné. * / ven.tisk("Ahoj světe!"); }}
Deklarace importu na vyžádání umožňují importovat všechna pole typu:
import statické java.lang.System. *; / * Tato forma prohlášení dělá vše pole ve třídě java.lang.System dostupná podle názvu a lze je místo toho použít dovozního prohlášení v předchozím příkladu. * /
Konstanty výčtu lze také použít při statickém importu. Například toto enum je v balíčku s názvem obrazovka
:
veřejnost výčet ColorName { ČERVENÉ, MODRÝ, ZELENÁ};
K načtení konstant výčtu je možné použít statické importní deklarace v jiné třídě:
import obrazovka.ColorName;import statické obrazovka.ColorName. *;veřejnost třída Tečky { / * Následující řádek odpovídá 'ColorName foo = ColorName.RED', a bez statického importu by to bylo nesprávné. * / ColorName foo = ČERVENÉ; prázdnota posun() { / * Následující řádek odpovídá: if (foo == ColorName.RED) foo = ColorName.BLUE; * / -li (foo == ČERVENÉ) foo = MODRÝ; }}
Operátoři
Operátoři v Javě jsou podobní operátorům v C ++. Neexistuje však žádný vymazat
provozovatel kvůli odvoz odpadu mechanismy v Javě a nejsou zde žádné operace ukazatele protože Java je nepodporuje. Dalším rozdílem je, že Java má nepodepsaný operátor posunu doprava (>>>
), zatímco signatura operátora pravého posunu C je závislá na typu. Operátoři v Javě nemohou být přetížený.
Přednost | Operátor | Popis | Asociativita |
---|---|---|---|
1 | () | Vyvolání metody | Zleva do prava |
[] | Pole přístup | ||
. | Výběr člena třídy | ||
2 | ++ -- | Přírůstek a úbytek postfixu[1] | |
3 | ++ -- | Přírůstek a úbytek prefixu | Zprava doleva |
+ - | Unární plus a mínus | ||
! ~ | Logické NE a bitové NE | ||
(typ) val | Typ obsazení | ||
Nový | Vytvoření instance třídy nebo pole | ||
4 | * / % | Násobení, dělení a modul (zbytek) | Zleva do prava |
5 | + - | Sčítání a odčítání | |
+ | Zřetězení řetězců | ||
6 | << >> >>> | bitový levý posun, podepsaný pravý posun a nepodepsaný pravý posun | |
7 | < <= | Relační „Menší než“ a „menší než nebo rovno“ | |
> >= | Relační „větší než“ a „větší než nebo rovno“ | ||
instanceof | Porovnání typů | ||
8 | == != | Relační „rovná se“ a „nerovná se“ | |
9 | & | Bitové a logické AND | |
10 | ^ | Bitový a logický XOR (exkluzivní nebo) | |
11 | | | Bitové a logické OR (včetně nebo) | |
12 | && | Logické podmíněné AND | |
13 | || | Logické podmíněné OR | |
14 | C ? t : F | Trojice podmíněné (viz ?: ) | Zprava doleva |
15 | = | Jednoduché přiřazení | |
+= -= | Přiřazení podle součtu a rozdílu | ||
*= /= %= | Přiřazení podle produktu, podílu a zbytku | ||
<<= >>= >>>= | Přiřazení bitovým posunem doleva, podepsaným pravým posunem a nepodepsaným pravým posunem | ||
&= ^= |= | Přiřazení bitovým AND, XOR a OR |
Kontrolní struktury
Podmíněná prohlášení
-li
prohlášení
pokud prohlášení v Javě jsou podobné těm v C a používají stejnou syntaxi:
-li (i == 3) dělej něco();
-li
prohlášení může obsahovat nepovinné jiný
blok, v takovém případě se stane příkazem if-then-else:
-li (i == 2) { dělej něco();} jiný { doSomethingElse();}
Stejně jako C, else-if konstrukce nezahrnuje žádná speciální klíčová slova, je vytvořena jako posloupnost samostatných příkazů if-then-else:
-li (i == 3) { dělej něco();} jiný -li (i == 2) { doSomethingElse();} jiný { doSomethingDifferent();}
Všimněte si také, že ?: operátor lze použít místo jednoduchého příkazu if, například
int A = 1;int b = 2;int minVal = (A < b) ? A : b;
přepínač
prohlášení
Přepnout prohlášení v Javě lze použít byte
, krátký
, char
, a int
(poznámka: ne dlouho
) primitivní datové typy nebo jejich odpovídající typy obalů. Počínaje verzí J2SE 5.0 je možné používat typy výčtu. Počínaje Java SE 7 je možné používat řetězce. Jiné referenční typy nelze použít v přepínač
prohlášení.
Možné hodnoty jsou uvedeny pomocí případ
štítky. Tyto štítky v Javě mohou obsahovat pouze konstanty (včetně konstant enum a řetězcových konstant). Provádění začne po štítku odpovídajícím výrazu v závorkách. Volitelné výchozí
štítek může být přítomen, aby deklaroval, že následující kód bude spuštěn, pokud žádný z popisků případů neodpovídá výrazu.
Kód pro každý štítek končí znakem přestávka
klíčové slovo. Je možné jej vynechat, což způsobí, že provádění přejde k dalšímu štítku, nicméně během kompilace bude obvykle hlášeno varování.
přepínač (ch) { případ 'A': dělej něco(); // Spuštěno, pokud ch == 'A' přestávka; případ 'B': případ 'C': doSomethingElse(); // Spustí se, pokud ch == 'B' nebo ch == 'C' přestávka; výchozí: doSomethingDifferent(); // Spustí se v jakémkoli jiném případě přestávka;}
přepínač
výrazy
Od prostředí Java 14 je možné používat výrazy přepínačů, které používají novou syntaxi šipek:
var výsledek = přepínač (ch) { případ 'A' -> Výsledek.SKVĚLÝ; případ 'B', 'C' -> Výsledek.POKUTA; výchozí -> házet Nový ThisIsNoGoodException();};
Alternativně existuje možnost vyjádřit to samé s výtěžek
příkaz, i když se doporučuje upřednostňovat syntaxi šipky, protože se tak vyhne problému náhodných propadů.
var výsledek = přepínač (ch) { případ 'A': výtěžek Výsledek.SKVĚLÝ; případ 'B': případ 'C': výtěžek Výsledek.POKUTA; výchozí: házet Nový ThisIsNoGoodException();};
Iterační prohlášení
Iterační příkazy jsou příkazy, které se opakovaně provádějí, když je daná podmínka vyhodnocena jako pravdivá. Od té doby J2SE 5.0 „Java má čtyři podoby takových prohlášení.
zatímco
smyčka
V zatímco
smyčka, test se provádí před každou iterací.
zatímco (i < 10) { dělej něco();}
dělat, zatímco
smyčka
V dělat, zatímco
smyčka, test se provádí po každé iteraci. V důsledku toho je kód vždy proveden alespoň jednou.
// doSomething () je volán alespoň jednoudělat { dělej něco();} zatímco (i < 10);
pro
smyčka
pro
smyčky v Javě zahrnují inicializátor, podmínku a výraz čítače. Je možné zahrnout několik výrazů stejného druhu pomocí čárky jako oddělovače (kromě podmínky). Na rozdíl od C je však čárka pouze oddělovač a nikoli operátor.
pro (int i = 0; i < 10; i++) { dělej něco();} // Složitější smyčka využívající dvě proměnnépro (int i = 0, j = 9; i < 10; i++, j -= 3) { dělej něco();}
Stejně jako C jsou všechny tři výrazy volitelné. Následující smyčka je nekonečná:
pro (;;) { dělej něco();}
Vylepšeno pro
smyčka
Vylepšeno pro
smyčky jsou k dispozici od J2SE 5.0. Tento typ smyčky používá integrované iterátory nad poli a kolekcemi k vrácení každé položky v dané kolekci. Každý prvek je vrácen a dosažitelný v kontextu bloku kódu. Když je blok proveden, je vrácena další položka, dokud nezůstanou žádné položky. Na rozdíl od C#, tento druh smyčky nezahrnuje speciální klíčové slovo, ale místo toho používá jiný styl notace.
pro (int i : intArray) { dělej něco(i);}
Přejít na příkazy
Štítky
Štítky jsou uvedeny v kódu, který používá přestávka
a pokračovat
prohlášení. Všimněte si, že Java jít do
klíčové slovo nelze použít ke skoku na konkrétní body v kódu.
Start:someMethod();
přestávka
prohlášení
The přestávka
příkaz se vylomí z nejbližší smyčky nebo přepínač
prohlášení. Provádění pokračuje ve výpisu po ukončeném příkazu, pokud existuje.
pro (int i = 0; i < 10; i++) { zatímco (skutečný) { přestávka; } // Přeruší se až do tohoto bodu}
Z vnější smyčky je možné se vymanit pomocí štítků:
vnější:pro (int i = 0; i < 10; i++) { zatímco (skutečný) { přestávka vnější; }}// Přeruší se až do tohoto bodu
pokračovat
prohlášení
The pokračovat
příkaz přeruší aktuální iteraci aktuálního ovládacího příkazu a zahájí další iteraci. Následující zatímco
smyčka v níže uvedeném kódu čte znaky voláním getChar ()
, přeskakování příkazů v těle smyčky, pokud jsou znaky mezery:
int ch;zatímco (ch == getChar()) { -li (ch == ' ') { pokračovat; // Přeskočí zbytek smyčky while } // Zbytek smyčky while, nebude dosažen, pokud ch == '' dělej něco();}
Štítky lze specifikovat v pokračovat
prohlášení a přestávka
prohlášení:
vnější:pro (Tětiva str : stringsArr) { char[] strChars = str.toCharArray(); pro (char ch : strChars) { -li (ch == ' ') { / * Pokračuje ve vnějším cyklu a v dalším řetězec je získán z stringsArr * / pokračovat vnější; } dělej něco(ch); }}
vrátit se
prohlášení
The vrátit se
příkaz se používá k ukončení provádění metody ak vrácení hodnoty. Hodnota vrácená metodou se zapíše za vrátit se
klíčové slovo. Pokud metoda vrátí něco jiného než prázdnota
, musí používat vrátit se
příkaz vrátit nějakou hodnotu.
prázdnota dělej něco(booleovský streamClosed) { // Pokud má streamClosed hodnotu true, provádění se zastaví -li (streamClosed) { vrátit se; } readFromStream();}int vypočítat součet(int A, int b) { int výsledek = A + b; vrátit se výsledek;}
vrátit se
příkaz ukončí provádění okamžitě, s výjimkou jednoho případu: pokud je příkaz nalezen v rámci Snaž se
blok a je doplněn a Konečně
, kontrola je předána do Konečně
blok.
prázdnota dělej něco(booleovský streamClosed) { Snaž se { -li (streamClosed) { vrátit se; } readFromStream(); } Konečně { / * Bude volán jako poslední, i když readFromStream () nebyl volán * / freeResources(); }}
Výkazy zpracování výjimek
zkus chytit-konečně
prohlášení
Výjimky jsou spravovány uvnitř Snaž se
... chytit
bloky.
Snaž se { // Příkazy, které mohou vyvolat výjimky methodThrowingExceptions();} chytit (Výjimka např) { // Výjimka je zde zachycena a zpracována reportException(např);} Konečně { // Příkazy vždy prováděné po blocích try / catch freeResources();}
Prohlášení v rámci Snaž se
blok se provede, a pokud některý z nich vyvolá výjimku, provedení bloku se přeruší a výjimka je zpracována chytit
blok. Může jich být více chytit
bloky, v tom případě se provede první blok s proměnnou výjimky, jejíž typ odpovídá typu vyvolané výjimky.
Java SE 7 kromě klauzulí uni-catch také zavedla klauzule s více úlovky. Tento typ klauzulí catch umožňuje Javě zpracovávat různé typy výjimek v jednom bloku za předpokladu, že nejsou navzájem podtřídami.
Snaž se { methodThrowingExceptions();} chytit (IOException | IllegalArgumentException např) { // IOException a IllegalArgumentException zde budou zachyceny a zpracovány reportException(např);}
Jestli ne chytit
block odpovídá typu vyvolané výjimky, provedení vnějšího bloku (nebo metody) obsahujícího Snaž se
... chytit
příkaz je přerušen a výjimka je předána a mimo obsahující blok (nebo metodu). Výjimka se šíří nahoru prostřednictvím zásobník volání až do shody chytit
blok se nachází v jedné z aktuálně aktivních metod. Pokud se výjimka šíří až na nejvyšší úroveň hlavní
metoda bez shody chytit
nalezený blok se do standardního výstupního proudu zapíše textový popis výjimky.
Prohlášení v rámci Konečně
blok jsou vždy provedeny po Snaž se
a chytit
bloky, bez ohledu na to, zda byla vyvolána výjimka, ai když a vrátit se
bylo dosaženo prohlášení. Takové bloky jsou užitečné pro poskytnutí vyčištění kódu, který je zaručeno, že bude vždy proveden.
The chytit
a Konečně
bloky jsou volitelné, ale alespoň jeden nebo druhý musí být přítomen za Snaž se
blok.
Snaž se
-s-prostředky prohlášení
Snaž se
Příkazy -with-resources jsou speciální typ zkuste chytit-konečně
prohlášení zavedená jako implementace zlikvidovat vzor v prostředí Java SE 7. V a Snaž se
-s-prostředky prohlášení Snaž se
po klíčovém slově následuje inicializace jednoho nebo více zdrojů, které se uvolní automaticky, když Snaž se
spuštění bloku je dokončeno. Zdroje musí být implementovány java.lang.AutoCloseable
. Snaž se
-With-resources prohlášení nejsou povinni mít chytit
nebo Konečně
blok na rozdíl od normálu zkuste chytit-konečně
prohlášení.
Snaž se (FileOutputStream fos = Nový FileOutputStream("název souboru"); XMLEncoder xEnc = Nový XMLEncoder(fos)) { xEnc.writeObject(objekt);} chytit (IOException např) { Logger.getLogger(Serializátor.třída.getName()).log(Úroveň.TĚŽKÉ, nula, např);}
Vzhledem k tomu, Java 9 je možné použít již deklarované proměnné:
FileOutputStream fos = Nový FileOutputStream("název souboru");XMLEncoder xEnc = Nový XMLEncoder(fos);Snaž se (fos; xEnc) { xEnc.writeObject(objekt);} chytit (IOException např) { Logger.getLogger(Serializátor.třída.getName()).log(Úroveň.TĚŽKÉ, nula, např);}
házet
prohlášení
The házet
příkaz se používá k vyvolání výjimky a ukončení provádění bloku nebo metody. Vyvolaná instance výjimky je zapsána za házet
prohlášení.
prázdnota methodThrowingExceptions(Objekt obj) { -li (obj == nula) { // Vyvolá výjimku typu NullPointerException házet Nový NullPointerException(); } // Nebude volán, pokud je objekt null doSomethingWithObject(obj);}
Řízení souběžnosti vláken
Java má vestavěné nástroje pro vícevláknové programování. Pro účely vlákna synchronizace the synchronizované
příkaz je obsažen v jazyce Java.
Chcete-li synchronizovat blok kódu, předchází jej synchronizované
klíčové slovo následované zámkem v závorce. Když vykonávající vlákno dosáhne synchronizovaného bloku, získá a vzájemné vyloučení zámek, provede blok a poté zámek uvolní. Do uvolnění zámku nesmí do tohoto bloku vstoupit žádná vlákna. Jako zámek lze použít jakýkoli nenulový referenční typ.
/ * Získá zámek u některých objektů. Musí to býtreferenční typ a musí mít nenulovou hodnotu * /synchronizované (someObject) { // Synchronizované příkazy}
tvrdit
prohlášení
tvrdit
prohlášení jsou k dispozici od roku J2SE 1.4. Používají se tyto typy příkazů tvrzení ve zdrojovém kódu, který lze zapnout a vypnout během provádění pro konkrétní třídy nebo balíčky. Prohlásit tvrzení tvrdit
je použito klíčové slovo následované podmíněným výrazem. Pokud se to vyhodnotí na Nepravdivé
při provedení příkazu je vyvolána výjimka. Toto prohlášení může obsahovat dvojtečku následovanou dalším výrazem, který bude fungovat jako podrobná zpráva výjimky.
// Pokud n se rovná 0, je vyvolána AssertionErrortvrdit n != 0;/ * Je-li n rovno 0, bude vyvolána AssertionErrorse zprávou za dvojtečkou * /tvrdit n != 0 : „n bylo rovno nule“;
Primitivní typy
Primitivní typy v Javě zahrnují celočíselné typy, čísla s plovoucí desetinnou čárkou, UTF-16 kódové jednotky a booleovský typ. V Javě neexistují žádné nepodepsané typy kromě char
typu, který se používá k reprezentaci kódových jednotek UTF-16. Nedostatek nepodepsaných typů je kompenzován zavedením nepodepsané operace posunu doprava (>>>
), který není v C ++ přítomen. Přesto však byla kritizována nedostatečná kompatibilita s C a C ++, která to způsobuje.[2]
Primitivní typy | |||||
---|---|---|---|---|---|
Zadejte název | Obalová třída | Hodnota | Rozsah | Velikost | Výchozí hodnota |
byte | java.lang.Byte | celé číslo | -128 až +127 | 8bitový (1 bajt) | 0 |
krátký | java.lang. krátká | celé číslo | -32 768 až + 32 767 | 16 bitů (2 bajty) | 0 |
int | java.lang.Integer | celé číslo | −2 147 483 648 až + 2 147 483 647 | 32 bitů (4 bajty) | 0 |
dlouho | java.lang.Long | celé číslo | −9 223 372 036 854 775 808 až +9,223,372,036,854,775,807 | 64bitový (8 bajtů) | 0 |
plovák | java.lang.Float | číslo s plovoucí desetinnou čárkou | ± 1,401298E −45 až ± 3,402823E + 38 | 32 bitů (4 bajty) | 0,0f [3] |
dvojnásobek | java.lang.Double | číslo s plovoucí desetinnou čárkou | ± 4,94065645841246E − 324 až ± 1,79769313486232E + 308 | 64bitový (8 bajtů) | 0.0 |
booleovský | java.lang.Boolean | Booleovský | skutečný nebo Nepravdivé | 1-bit (1-bit) | Nepravdivé |
char | java.lang. znak | UTF-16 kódová jednotka (BMP charakter nebo část náhradního páru) | „ u0000“ přes ' uFFFF' | 16 bitů (2 bajty) | „ u0000“ |
char
nemusí nutně odpovídat jednomu znaku. Může představovat součást a náhradní pár, v takovém případě je bod kódu Unicode reprezentován posloupností dvou char
hodnoty.
Box a rozbalení
Tato jazyková funkce byla představena v J2SE 5.0. Box je operace převodu hodnoty primitivního typu na hodnotu odpovídajícího referenčního typu, která slouží jako obal pro tento konkrétní primitivní typ. Rozbalení je zpětná operace převodu hodnoty referenčního typu (dříve zabaleného) na hodnotu odpovídajícího primitivního typu. Ani jedna operace nevyžaduje explicitní převod.
Příklad:
int foo = 42; // Primitivní typCelé číslo bar = foo; / * foo je orámováno barem, bar je typu Integer, který slouží jako obal pro int * /int foo2 = bar; // Unboxed zpět na primitivní typ
Referenční typy
Mezi typy odkazů patří typy tříd, typy rozhraní a typy polí. Při volání konstruktoru se na haldě vytvoří objekt a proměnné se přiřadí odkaz. Když se proměnná objektu dostane mimo rozsah, odkaz se rozbije a když už žádné odkazy nezbývají, objekt se označí jako odpad. Sběratel odpadu to poté sbírá a ničí.
Referenční proměnná je nula
když neodkazuje na žádný objekt.
Pole
Pole v Javě se vytvářejí za běhu, stejně jako instance třídy. Délka pole je definována při vytváření a nelze ji změnit.
int[] čísla = Nový int[5];čísla[0] = 2;čísla[1] = 5;int X = čísla[0];
Inicializátory
// Dlouhá syntaxeint[] čísla = Nový int[] {20, 1, 42, 15, 34};// Krátká syntaxeint[] čísla2 = {20, 1, 42, 15, 34};
Vícerozměrná pole
V Javě jsou vícerozměrná pole představována jako pole polí. Technicky jsou reprezentovány poli odkazů na jiná pole.
int[][] čísla = Nový int[3][3];čísla[1][2] = 2;int[][] čísla2 = {{2, 3, 2}, {1, 2, 6}, {2, 4, 5}};
Vzhledem k povaze vícerozměrných polí se mohou dílčí pole lišit v délce, takže vícerozměrná pole nejsou na rozdíl od C vázána jako obdélníková:
int[][] čísla = Nový int[2][]; // Inicializace pouze první dimenzečísla[0] = Nový int[3];čísla[1] = Nový int[2];
Třídy
Třídy jsou základy objektově orientovaného jazyka, jako je Java. Obsahují členy, kteří ukládají a manipulují s daty. Třídy jsou rozděleny do nejvyšší úroveň a vnořené. Vnořené třídy jsou třídy umístěné uvnitř jiné třídy, které mohou přistupovat k soukromým členům obklopující třídy. Vnořené třídy zahrnují členské třídy (které lze definovat pomocí statický modifikátor pro jednoduché vnoření nebo bez něj pro vnitřní třídy), místní třídy a anonymní třídy.
Prohlášení
Třída nejvyšší úrovně | třída Foo { // Členové třídy} |
---|---|
Vnitřní třída | třída Foo { // Třída nejvyšší úrovně třída Bar { // Vnitřní třída }} |
Vnořená třída | třída Foo { // Třída nejvyšší úrovně statický třída Bar { // Vnořená třída }} |
Místní třída | třída Foo { prázdnota bar() { třída Foobar {// Místní třída v rámci metody } }} |
Anonymní třída | třída Foo { prázdnota bar() { Nový Objekt() {// Vytvoření nové anonymní třídy rozšiřující objekt }; }} |
Instance
Nestatické členy třídy definují typy proměnných instance a metody, které souvisejí s objekty vytvořenými z této třídy. Chcete-li vytvořit tyto objekty, je nutné vytvořit instanci třídy pomocí Nový
operátor a volání konstruktoru třídy.
Foo foo = Nový Foo();
Přistupující členové
Členy obou instancí a statických tříd jsou přístupné pomocí .
(tečka) operátor.
Přístup k členovi instance
Ke členům instance lze přistupovat pomocí názvu proměnné.
Tětiva foo = "Ahoj";Tětiva bar = foo.toUpperCase();
Přístup ke statickému členu třídy
Ke statickým členům se přistupuje pomocí názvu třídy nebo jiného typu. To nevyžaduje vytvoření instance třídy. Statické členy jsou deklarovány pomocí statický
modifikátor.
veřejnost třída Foo { veřejnost statický prázdnota dělej něco() { }}// Volání statické metodyFoo.dělej něco();
Modifikátory
Modifikátory jsou klíčová slova používaná k úpravě deklarací typů a členů typu. Nejvýznamnější je podskupina obsahující modifikátory přístupu.
abstraktní
- Určuje, že třída slouží pouze jako základní třída a nelze ji vytvořit instancí.statický
- Používá se pouze pro členské třídy, určuje, že členská třída nepatří ke konkrétní instanci třídy obsahující.finále
- Třídy označené jakofinále
nelze rozšířit z a nemůže mít žádné podtřídy.strictfp
- Určuje, že všechny operace s plovoucí desetinnou čárkou musí být prováděny v souladu s IEEE 754 a zakazuje používat zvýšenou přesnost k ukládání průběžných výsledků.
Modifikátory přístupu
The modifikátory přístupunebo modifikátory dědičnosti, nastavit přístupnost tříd, metod a dalších členů. Členové označeni jako veřejnost
je k dispozici odkudkoli. Pokud třída nebo její člen nemá žádné modifikátory, předpokládá se výchozí přístup.
veřejnost třída Foo { int jít() { vrátit se 0; } soukromé třída Bar { }}
Následující tabulka ukazuje, zda má kód ve třídě přístup ke třídě nebo metodě v závislosti na umístění třídy přístupu a modifikátoru pro přístupnou třídu nebo člena třídy:
Modifikátor | Stejná třída nebo vnořená třída | Jiná třída uvnitř stejného balíčku | Rozšířená třída v jiném balíčku | Nevysunutý uvnitř jiného balíčku |
---|---|---|---|---|
soukromé | Ano | Ne | Ne | Ne |
výchozí (balíček soukromý) | Ano | Ano | Ne | Ne |
chráněný | Ano | Ano | Ano | Ne |
veřejnost | Ano | Ano | Ano | Ano |

Konstruktory a inicializátory
A konstruktor je speciální metoda volaná při inicializaci objektu. Jeho účelem je inicializovat členy objektu. Hlavní rozdíly mezi konstruktory a běžnými metodami spočívají v tom, že konstruktory jsou volány pouze tehdy, když je vytvořena instance třídy a nikdy nic nevrátí. Konstruktory jsou deklarovány jako běžné metody, ale jsou pojmenovány po třídě a není zadán žádný návratový typ:
třída Foo { Tětiva str; Foo() { // Konstruktor bez argumentů // Inicializace } Foo(Tětiva str) { // Konstruktor s jedním argumentem tento.str = str; }}
Inicializátory jsou bloky kódu, které se provedou při vytvoření třídy nebo instance třídy. Existují dva druhy inicializátorů, statické inicializátory a inicializátory instance.
Statické inicializátory inicializují statická pole při vytváření třídy. Jsou deklarovány pomocí statický
klíčové slovo:
třída Foo { statický { // Inicializace }}
Třída je vytvořena pouze jednou. Proto statické inicializátory nejsou volány více než jednou. Naopak, inicializátory instancí jsou automaticky volány před voláním konstruktoru pokaždé, když je vytvořena instance třídy. Na rozdíl od konstruktorů instance nemohou inicializátory přijímat žádné argumenty a obecně nemohou házet žádné kontrolované výjimky (s výjimkou několika zvláštních případů). Inicializátory instancí jsou deklarovány v bloku bez jakýchkoli klíčových slov:
třída Foo { { // Inicializace }}
Protože Java má mechanismus sběru odpadků, neexistují žádné destruktory. Každý objekt však má a dokončit()
metoda volaná před sběrem odpadu, což může být přepsán realizovat finalizaci.
Metody
Všechny příkazy v Javě musí být umístěny v rámci metod. Metody jsou podobné funkcím, kromě toho, že patří do tříd. Metoda má návratovou hodnotu, název a obvykle některé parametry inicializované, když je volána s některými argumenty. Podobně jako v C ++, metody vracející nic nemají návratový typ deklarovaný jako prázdnota
. Na rozdíl od C ++ nemohou mít metody v Javě výchozí argument hodnoty a metody jsou obvykle přetíženy.
třída Foo { int bar(int A, int b) { vrátit se (A*2) + b; } / * Přetížená metoda se stejným názvem, ale odlišnou sadou argumentů * / int bar(int A) { vrátit se A*2; }}
Metoda se nazývá using .
notace na objektu, nebo v případě statické metody také na název třídy.
Foo foo = Nový Foo();int výsledek = foo.bar(7, 2); // Nestatická metoda se volá fooint konečný výsledek = Matematika.břišní svaly(výsledek); // Volání statické metody
The hodí
klíčové slovo označuje, že metoda vyvolá výjimku. Všechny zaškrtnuté výjimky musí být uvedeny v seznamu odděleném čárkami.
prázdnota openStream() hodí IOException, myException { // Označuje, že může být vyvolána výjimka IOException}
Modifikátory
abstraktní
- Abstraktní metody může být přítomen pouze v abstraktní třídy, takové metody nemají žádné tělo a musí být přepsány v podtřídě, pokud není sama o sobě abstraktní.statický
- Zpřístupní metodu statickou a přístupnou bez vytvoření instance třídy. Statické metody však nemohou přistupovat k nestatickým členům ve stejné třídě.finále
- Deklaruje, že metodu nelze přepsat v podtřídě.rodák
- Označuje, že tato metoda je implementována prostřednictvím JNI v kódu závislém na platformě. Skutečná implementace probíhá mimo kód Java a tyto metody nemají tělo.strictfp
- Prohlašuje přísný soulad s IEEE 754 při provádění operací s plovoucí desetinnou čárkou.synchronizované
- Prohlašuje, že vlákno provádějící tuto metodu musí získat monitor. Prosynchronizované
metody monitor je instance třídy nebojava.lang.Class
pokud je metoda statická.- Modifikátory přístupu - identické s těmi, které se používají u tříd
Varargs
Tato jazyková funkce byla představena v J2SE 5.0. Poslední argument metody může být deklarován jako parametr variabilní arity, v takovém případě se metoda stane metodou variabilní arity (na rozdíl od metod fixní arity) nebo jednoduše varargy metoda. To umožňuje předat metodě proměnný počet hodnot deklarovaného typu jako parametry - včetně bez parametrů. Tyto hodnoty budou uvnitř metody k dispozici jako pole.
prázdnota printReport(Tětiva záhlaví, int... čísla) { // čísla představují varargy Systém.ven.tisk(záhlaví); pro (int počet : čísla) { Systém.ven.tisk(počet); }}// Volání metody varargsprintReport(„Report data“, 74, 83, 25, 96);
Pole
Pole nebo proměnné třídy lze deklarovat uvnitř těla třídy pro ukládání dat.
třída Foo { dvojnásobek bar;}
Pole lze inicializovat přímo, když jsou deklarována.
třída Foo { dvojnásobek bar = 2.3;}
Modifikátory
statický
- Nastaví pole na statický člen.finále
- Umožňuje pole inicializovat pouze jednou v konstruktoru nebo uvnitř inicializačního bloku nebo během jeho deklarace, podle toho, co nastane dříve.přechodný
- Označuje, že toto pole nebude uloženo během serializace.nestálý
- Pokud je pole deklarovánonestálý
, je zajištěno, že všechna vlákna vidí konzistentní hodnotu proměnné.
Dědictví
Třídy v Javě mohou pouze zdědit z jeden třída. Třídu lze odvodit z jakékoli třídy, která není označena jako finále
. Dědičnost je deklarována pomocí rozšiřuje
klíčové slovo. Třída se může odkazovat pomocí tento
klíčové slovo a jeho přímá nadtřída pomocí super
klíčové slovo.
třída Foo {}třída Foobar rozšiřuje Foo {}
Pokud třída neurčí svou nadtřídu, implicitně dědí z java.lang.Object
třída. Všechny třídy v Javě jsou tedy podtřídami Objekt
třída.
Pokud nadtřída nemá konstruktor bez parametrů, musí podtřída ve svých konstruktorech určit, jaký konstruktor nadtřídy se má použít. Například:
třída Foo { veřejnost Foo(int n) { // Udělejte něco s n }}třída Foobar rozšiřuje Foo { soukromé int číslo; // Superclass nemá konstruktor bez parametrů // takže musíme určit, jaký konstruktor naší nadtřídy použít a jak veřejnost Foobar(int číslo) { super(číslo); tento.číslo = číslo; }}
Prvořadé metody
Na rozdíl od C ++ jsou všechnyfinále
metody v Javě jsou virtuální a lze je přepsat zděděnými třídami.
třída Úkon { veřejnost int dělej něco() { vrátit se 0; }}třída NewOperation rozšiřuje Úkon { @ Přepis veřejnost int dělej něco() { vrátit se 1; }}
Abstraktní třídy
An Abstraktní třída je třída, která je neúplná nebo má být považována za neúplnou. Normální třídy mohou mít abstraktní metody, tj. metody, které jsou deklarovány, ale ještě nejsou implementovány, pouze pokud se jedná o abstraktní třídy. Třída C má abstraktní metody, pokud některá z následujících je pravda:
- C výslovně obsahuje deklaraci abstraktní metody.
- Kterákoli ze superclassů C má abstraktní metodu a C ani nedeklaruje, ani nezdědí metodu, která ji implementuje.
- Přímé superinterface C deklaruje nebo dědí metodu (která je tedy nutně abstraktní) a C ani deklaruje, ani nedědí metodu, která ji implementuje.
- Může být vytvořena instance podtřídy abstraktní třídy, která není sama abstraktní, což má za následek provedení konstruktoru pro abstraktní třídu, a proto provedení inicializátorů pole pro proměnné instance této třídy.
balík org.dwwwp.test;/** * @author jcrypto */veřejnost třída AbstractClass { soukromé statický finále Tětiva Ahoj; statický { Systém.ven.tisk(AbstractClass.třída.getName() + ": běh statického bloku"); Ahoj = "Ahoj z " + AbstractClass.třída.getName(); } { Systém.ven.tisk(AbstractClass.třída.getName() + ": modul runtime instance"); } veřejnost AbstractClass() { Systém.ven.tisk(AbstractClass.třída.getName() + ": runtime konstruktoru"); } veřejnost statický prázdnota Ahoj() { Systém.ven.tisk(Ahoj); }}
balík org.dwwwp.test;/** * @author jcrypto */veřejnost třída CustomClass rozšiřuje AbstractClass { statický { Systém.ven.tisk(CustomClass.třída.getName() + ": běh statického bloku"); } { Systém.ven.tisk(CustomClass.třída.getName() + ": modul runtime instance"); } veřejnost CustomClass() { Systém.ven.tisk(CustomClass.třída.getName() + ": runtime konstruktoru"); } veřejnost statický prázdnota hlavní(Tětiva[] args) { CustomClass nc = Nový CustomClass(); Ahoj(); //AbstractClass.hello();// také platné }}
Výstup:
org.dwwwp.test.AbstractClass: statický blok runtimeorg.dwwwp.test.CustomClass: statický blok runtimeorg.dwwwp.test.AbstractClass: blok instance runtimeorg.dwwwp.test.AbstractClass: konstruktor runtimeorg.dwwwp.test.CustomClass: blok instance runtimeorg .dwwwp.test.CustomClass: runtimehello konstruktoru z org.dwwwp.test.AbstractClass
Výčty
Tato jazyková funkce byla představena v J2SE 5.0. Technicky výčty jsou druh třídy obsahující v jeho těle konstanty výčtu. Každá konstanta výčtu definuje instanci typu výčtu. Třídy výčtu nelze vytvořit kdekoli, kromě samotné třídy výčtu.
výčet Sezóna { ZIMA, JARO, LÉTO, PODZIM}
Konstanty výčtu mohou mít konstruktory, které jsou volány při načtení třídy:
veřejnost výčet Sezóna { ZIMA("Studený"), JARO("Ohřívač"), LÉTO("Horký"), PODZIM("Chladič"); Sezóna(Tětiva popis) { tento.popis = popis; } soukromé finále Tětiva popis; veřejnost Tětiva getDescription() { vrátit se popis; }}
Výčty mohou mít těla třídy, v takovém případě se s nimi zachází jako s anonymními třídami rozšiřujícími třídu enum:
veřejnost výčet Sezóna { ZIMA { Tětiva getDescription() {vrátit se "Studený";} }, JARO { Tětiva getDescription() {vrátit se "ohřívač";} }, LÉTO { Tětiva getDescription() {vrátit se "horký";} }, PODZIM { Tětiva getDescription() {vrátit se "chladič";} };}
Rozhraní
Rozhraní jsou typy, které neobsahují žádná pole a obvykle definují řadu metod bez skutečné implementace. Jsou užitečné k definování smlouvy s libovolným počtem různých implementací. Každé rozhraní je implicitně abstraktní. Metody rozhraní mohou mít podmnožinu modifikátorů přístupu v závislosti na jazykové verzi, strictfp
, který má stejný účinek jako pro třídy, a také statický
od Java SE 8.
rozhraní ActionListener { int ACTION_ADD = 0; int ACTION_REMOVE = 1; prázdnota actionSelected(int akce);}
Implementace rozhraní
Rozhraní je implementováno třídou pomocí nářadí
klíčové slovo. Je povoleno implementovat více než jedno rozhraní, v takovém případě jsou zapsány později nářadí
klíčové slovo v seznamu odděleném čárkami. Třída implementující rozhraní musí přepsat všechny jeho metody, jinak musí být deklarována jako abstraktní.
rozhraní RequestListener { int požadavek obdržen();}třída ActionHandler nářadí ActionListener, RequestListener { veřejnost prázdnota actionSelected(int akce) { } veřejnost int požadavek obdržen() { }}// Způsob volání definovaný rozhranímRequestListener posluchač = Nový ActionHandler(); / * ActionHandler může být reprezentován jako RequestListener ... * /posluchač.požadavek obdržen(); /*... a je tedy známo, že se implementuje metoda requestReceived () * /
Funkční rozhraní a výrazy lambda
Tyto funkce byly zavedeny vydáním Java SE 8. Rozhraní se automaticky stane funkčním rozhraním, pokud definuje pouze jednu metodu. V tomto případě může být implementace reprezentována jako výraz lambda namísto implementace v nové třídě, což značně zjednodušuje psaní kódu v funkční styl. Funkční rozhraní lze volitelně opatřit poznámkami @Funkčnírozhraní
anotace, která řekne kompilátoru, aby zkontroloval, zda rozhraní skutečně odpovídá definici funkčního rozhraní.
// Funkční rozhraní@Funkčnírozhranírozhraní Výpočet { int vypočítat(int nějaké číslo, int someOtherNumber);}// Metoda, která přijímá toto rozhraní jako parametrint runCalculation(Výpočet výpočet) { vrátit se výpočet.vypočítat(1, 2);}// Použití metody lambda k volání metodyrunCalculation((číslo, otherNumber) -> číslo + otherNumber);// Ekvivalentní kód, který místo toho používá anonymní třídurunCalculation(Nový Výpočet() { @ Přepis veřejnost int vypočítat(int nějaké číslo, int someOtherNumber) { vrátit se nějaké číslo + someOtherNumber; }})
Typy parametrů Lambdy nemusí být plně specifikovány a lze je odvodit z rozhraní, které implementuje. Lambda tělo lze psát bez bloku těla a vrátit se
prohlášení, pokud se jedná pouze o výraz. Také u těch rozhraní, která mají v metodě pouze jeden parametr, lze kulaté závorky vynechat.
// Stejné volání jako výše, ale s plně zadanými typy a blokem tělarunCalculation((int číslo, int otherNumber) -> { vrátit se číslo + otherNumber;});// Funkční rozhraní s metodou, která má pouze jeden parametrrozhraní StringExtender { Tětiva extendString(Tětiva vstup);}// Inicializace proměnné tohoto typu pomocí lambdaStringExtender prodlužovač = vstup -> vstup + „Rozšířené“;
Odkazy na metody
Není nutné používat lambdas, pokud již existuje pojmenovaná metoda kompatibilní s rozhraním. Tuto metodu lze předat místo lambda pomocí odkazu na metodu. Existuje několik typů odkazů na metody:
Typ reference | Příklad | Ekvivalentní lambda |
---|---|---|
Statický | Celé číslo :: součet | (number, otherNumber) -> number + otherNumber |
Vázaný | "LongString" :: podřetězec | index -> "LongString" .substring (index) |
bez závazků | String :: isEmpty | string -> string.isEmpty () |
Konstruktor třídy | ArrayList <řetězec> :: nový | kapacita -> nový ArrayList <řetězec> (kapacita) |
Konstruktor pole | Řetězec [] :: nový | size -> new String [size] |
Kód nad kterým volá runCalculation
lze nahradit následujícími pomocí odkazů na metody:
runCalculation(Celé číslo::součet);
Dědictví
Rozhraní mohou dědit z jiných rozhraní stejně jako třídy. Na rozdíl od tříd je povoleno dědit z více rozhraní. However, it is possible that several interfaces have a field with the same name, in which case it becomes a single ambiguous member, which cannot be accessed.
/* Class implementing this interface must implement methods of bothActionListener and RequestListener */rozhraní EventListener rozšiřuje ActionListener, RequestListener { }
Default methods
Java SE 8 introduced default methods to interfaces which allows developers to add new methods to existing interfaces without breaking compatibility with the classes already implementing the interface. Unlike regular interface methods, default methods have a body which will get called in the case if the implementing class doesn't override it.
rozhraní StringManipulator { Tětiva extendString(Tětiva vstup); // A method which is optional to implement výchozí Tětiva shortenString(Tětiva vstup) { vrátit se vstup.podřetězec(1); }}// This is a valid class despite not implementing all the methodstřída PartialStringManipulator nářadí StringManipulator { @ Přepis veřejnost Tětiva extendString(Tětiva vstup) { vrátit se vstup + " Extended"; }}
Static methods
Static methods is another language feature introduced in Java SE 8. They behave in exactly the same way as in the classes.
rozhraní StringUtils { statický Tětiva shortenByOneSymbol(Tětiva vstup) { vrátit se vstup.podřetězec(1); }}StringUtils.shortenByOneSymbol("Test");
Private methods
Private methods were added in the Java 9 release. An interface can have a method with a body marked as private, in which case it will not be visible to inheriting classes. It can be called from default methods for the purposes of code reuse.
rozhraní Logger { výchozí prázdnota logError() { log(Úroveň.CHYBA); } výchozí prázdnota logInfo() { log(Úroveň.INFO); } soukromé prázdnota log(Úroveň úroveň) { SystemLogger.log(úroveň.id); }}
Anotace
Annotations in Java are a way to embed metadata into code. This language feature was introduced in J2SE 5.0.
Annotation types
Java has a set of predefined annotation types, but it is allowed to define new ones. An annotation type declaration is a special type of an interface declaration. They are declared in the same way as the interfaces, except the rozhraní
keyword is preceded by the @
podepsat. All annotations are implicitly extended from java.lang.annotation.Annotation
and cannot be extended from anything else.
@rozhraní BlockingOperations {}
Annotations may have the same declarations in the body as the common interfaces, in addition they are allowed to include enums and annotations. The main difference is that abstract method declarations must not have any parameters or throw any exceptions. Also they may have a default value, which is declared using the výchozí
keyword after the method name:
@rozhraní BlockingOperations { booleovský fileSystemOperations(); booleovský networkOperations() výchozí Nepravdivé;}
Usage of annotations
Annotations may be used in any kind of declaration, whether it is package, class (including enums), interface (including annotations), field, method, parameter, constructor, or local variable. Also they can be used with enum constants. Annotations are declared using the @
sign preceding annotation type name, after which element-value pairs are written inside brackets. All elements with no default value must be assigned a value.
@BlockingOperations(/*mandatory*/ fileSystemOperations,/*optional*/ networkOperations = skutečný)prázdnota openOutputStream() { //Annotated method}
Besides the generic form, there are two other forms to declare an annotation, which are shorthands. Marker annotation is a short form, it is used when no values are assigned to elements:
@Unused // Shorthand for @Unused()prázdnota travelToJupiter() {}
The other short form is called single element annotation. It is used with annotations types containing only one element or in the case when multiple elements are present, but only one elements lacks a default value. In single element annotation form the element name is omitted and only value is written instead:
/* Equivalent for @BlockingOperations(fileSystemOperations = true).networkOperations has a default value anddoes not have to be assigned a value */@BlockingOperations(skutečný)prázdnota openOutputStream() {}
Generika
Generika nebo parametrizované typy nebo parametrický polymorfismus is one of the major features introduced in J2SE 5.0. Before generics were introduced, it was required to declare all the types explicitly. With generics it became possible to work in a similar manner with different types without declaring the exact types. The main purpose of generics is to ensure type safety and to detect runtime errors during compilation. Unlike C#, information on the used parameters is not available at runtime due to vymazání typu.[4]
Obecné třídy
Classes can be parameterized by adding a type variable inside angle brackets (<
a >
) following the class name. It makes possible the use of this type variable in class members instead of actual types. There can be more than one type variable, in which case they are declared in a comma-separated list.
It is possible to limit a type variable to a subtype of some specific class or declare an interface that must be implemented by the type. In this case the type variable is appended by the rozšiřuje
keyword followed by a name of the class or the interface. If the variable is constrained by both class and interface or if there are several interfaces, the class name is written first, followed by interface names with &
sign used as the delimiter.
/* This class has two type variables, T and V. T must be a subtype of ArrayList and implement Formattable interface */veřejnost třída Mapovač<T rozšiřuje ArrayList & Formattable, PROTI> { veřejnost prázdnota přidat(T pole, PROTI položka) { // array has add method because it is an ArrayList subclass pole.přidat(položka); }}
When a variable of a parameterized type is declared or an instance is created, its type is written exactly in the same format as in the class header, except the actual type is written in the place of the type variable declaration.
/* Mapper is created with CustomList as T and Integer as V.CustomList must be a subclass of ArrayList and implement Formattable */Mapovač<CustomList, Celé číslo> mapovač = Nový Mapovač<CustomList, Celé číslo>();
Since Java SE 7, it is possible to use a diamond (<>
) in place of type arguments, in which case the latter will be inferred. The following code in Java SE 7 is equivalent to the code in the previous example:
Mapovač<CustomList, Celé číslo> mapovač = Nový Mapovač<>();
When declaring a variable for a parameterized type, it is possible to use wildcards instead of explicit type names. Wildcards are expressed by writing ?
sign instead of the actual type. It is possible to limit possible types to the subclasses or superclasses of some specific class by writing the rozšiřuje
klíčové slovo nebo super
keyword correspondingly followed by the class name.
/* Any Mapper instance with CustomList as the first parametermay be used regardless of the second one.*/Mapovač<CustomList, ?> mapovač;mapovač = Nový Mapovač<CustomList, Booleovský>();mapovač = Nový Mapovač<CustomList, Celé číslo>();/* Will not accept types that use anything buta subclass of Number as the second parameter */prázdnota addMapper(Mapovač<?, ? rozšiřuje Číslo> mapovač) {}
Generic methods and constructors
Usage of generics may be limited to some particular methods, this concept applies to constructors as well. To declare a parameterized method, type variables are written before the return type of the method in the same format as for the generic classes. In the case of constructor, type variables are declared before the constructor name.
třída Mapovač { // The class itself is not generic, the constructor is <T, PROTI> Mapovač(T pole, PROTI položka) { }}/* This method will accept only arrays of the same type asthe searched item type or its subtype*/statický <T, PROTI rozšiřuje T> booleovský obsahuje(T položka, PROTI[] přílet) { pro (T currentItem : přílet) { -li (položka.rovná se(currentItem)) { vrátit se skutečný; } } vrátit se Nepravdivé;}
Obecná rozhraní
Interfaces can be parameterized in the similar manner as the classes.
rozhraní Rozšiřitelný<T rozšiřuje Číslo> { prázdnota addItem(T položka);}// This class is parameterizedtřída Pole<T rozšiřuje Číslo> nářadí Rozšiřitelný<T> { prázdnota addItem(T položka) { }}// And this is not and uses an explicit type insteadtřída IntegerArray nářadí Rozšiřitelný<Celé číslo> { prázdnota addItem(Celé číslo položka) { }}
Viz také
Reference
- ^ "Operators (The Java™ Tutorials > Learning the Java Language > Language Basics)". docs.oracle.com. Oracle and/or its affiliates. Citováno 2015-06-16.
- ^ Owens, Sean. "Java and unsigned int, unsigned short, unsigned byte, unsigned long, etc. (Or rather, the lack thereof)".
- ^ "Primitive Data Types".
- ^ Generics in the Run Time (C# Programming Guide)
- Patrick Naughton, Herbert Schildt. Java 2: The Complete Reference, third edition. The McGraw-Hill Companies, 1999. ISBN 0-07-211976-4
- Vermeulen; Ambler; Bumgardner; Metz; Misfeldt; Shur; Thompson (2000). The Elements of Java Style. Cambridge University Press. ISBN 0-521-77768-2.
- Gosling, Jamesi; Joy, Bille; Steele, chlapi; Bracha, Gillad (2005). Specifikace jazyka Java (3. vyd.). Addison-Wesley Professional. Citováno 2008-12-03.
externí odkazy
- The Java Language Specification, Third edition Authoritative description of the Java language
- Java SE 10 API Javadocs