1.7k likes | 1.9k Vues
Programovací jazyk Java. Dana Nejedlová. Použitá a doporučená literatura. Pavel Herout: Učebnice jazyka Java, nakladatelství Kopp, České Budějovice, 2008, ISBN 978-80-7232-355-5. Sylabus předmětu Moderní programování s další literaturou Internet dle odkazů na snímcích. Historie.
E N D
Programovací jazyk Java Dana Nejedlová
Použitá a doporučená literatura • Pavel Herout: Učebnice jazyka Java, nakladatelství Kopp, České Budějovice, 2008, ISBN 978-80-7232-355-5. • Sylabus předmětu Moderní programování s další literaturou • Internet dle odkazů na snímcích
Historie • 1990 – společnost Sun Microsystems řešila technologii programování vestavěných systémů. • Jazyk C++ měl dostatečné možnosti • je objektový (umožňuje modelování reality), ale • je příliš náročný na zdroje, • nemá management zdrojů (paměť, procesor), • je závislý na platformě. • Od poloviny 90. let minulého století se jazyk začal jmenovat Java a soustředil se na webové aplikace.
Charakteristika jazyka Java • objektovost • Objektově orientované programování, dále jen OOP, umožňuje modelovat reálný svět, ale programování objektů je obvykle složité. • Java umožňuje programovat objekty čitelnějším a bezpečnějším způsobem než jazyky původně procedurální, jako je C++. • OOP zvyšuje flexibilitu, modularitu a možnost znovupoužití kódu. • robustnost, ale … • Chybí pointery, které můžou způsobit přepsání paměti a únik paměti. • Java má mechanismus pro zachytávání chyb. • podpora distribuovaných výpočtů • Různé části programu mohou být vykonávány na různých počítačích. • podpora vícevláknových aplikací (multithreading) • Nutné pro práci s multimédii a sítěmi. • interpetovanost • Aplikace napsané v Javě jsou šířeny jako bytecode (druh mezijazyka) interpretovaný pomocí virtuálního stroje dostupného na mnoha platformách. • nezávislost na platformě, portabilita (architecture neutrality) • nižší rychlost, ale • u GUI aplikací (kvůli kterým Java vznikla především) to nevadí a • interpret Javy se vyvíjí (JIT compilation, HotSpot) • bezpečnost • Interpret kontroluje, zda program není škodlivý nebo nebezpečně napsaný. • dynamičnost • Nová část (třída - class) programu může být přidána bez nutnosti rekompilace.
Vznik programu v jazyce Java • Zdrojový kód je textový soubor s příponou „.java“. • Překladač přeloží zdrojový kód do mezijazyka zvaného bytecode a uloží jej v souboru s příponou „.class“. • součást JDK (Java Development Kit) • Interpreter (Java Virtual Machine – JVM) • ověří, že bytecode je bezpečný a • spustí bytecode. • součást JRE (Java Runtime Environment) • JRE je podmnožinou JDK.
Různé typy programů • aplikace • běžné programy, na které se zde omezíme • aplety • programy vestavěné ve webové stránce vykonávané klientem • V současnosti jsou místo nich běžnější Flash, a Microsoft Silverlight. • servlety • aplety vykonávané serverem • generované pomocí JSP (JavaServer Pages) • Alternativou jsou ASP a PHP. • dynamicky generované webové stránky
Vývojové nástroje • Jsou závislé na platformě. • Překladač a standardní knihovny • JDK SE - Standard Edition (www.oracle.com) • Knihovny se nazývají Java (Core) APIs a jsou dostupné na http://www.oracle.com/technetwork/java/javase/documentation/api-jsp-136079.html • IDE – vývojová prostředí • NetBeans, Eclipse
Struktura programu v jazyce Java javac -d . HelloWorldApp.java Adresář, kam se uloží soubor HelloWorldApp.class, je helloworldapp. package helloworldapp; /** * * @author <your name> */ public class HelloWorldApp { /** * @param args the command line arguments */ public static void main(String[] args) { System.out.println("Hello World!"); } } Dokumentační komentář Generuje se z něj dokumentace. Třída HelloWorldApp zapouzdřující metodu main Povinná hlavička hlavního programu – metody main Tělo metody main
Komentáře • utrata = pocetPiv * 15; // jednořádkový komentář • /* Komentářový blok neboli komentář na několik řádků */ • /** Dokumentační komentář, ze kterého se vytvoří dokumentace pomocí programu javadoc.exe */ • Musí se vyskytnout bezprostředně před názvem třídy nebo metody. • Používají se v něm značky (tags) @. • javadoc -author -d MojeDokumentace Prvni.java • příkaz, který vygeneruje dokumentaci do adresáře MojeDokumentace • Komentáře nelze vnořovat do komentářů.
Identifikátory • Java rozlišuje malá a velká písmena. • Identifikátory Java API se často liší jen velikostí písmen. • Je nutno dodržovat konvence: • třídy a rozhraní • AccessibleContext, Double • metody, proměnné, datové typy, klíčová slova • accessibleContext, double • V dokumentaci se proměnné od metod liší tím, že metody mají za jménem uvedeny prázdné kulaté závorky. • balíky (packages) • helloworldapp, java.lang • konstanty • MAX_VALUE • Délka identifikátorů není omezena. • Každý identifikátor musí začínat písmenem nebo podtržítkem.
Anotace (annotation) • značky (metadata, tags) vkládané do zdrojového kódu a určené většinou pro různé nástroje, které s daným programem pracují. • Mohou být zpracovány ve třech různých etapách práce s programem: • při práci se zdrojovým kódem • Využívá javadoc či překladač. • Mohou být začleněny do přeloženého .class souboru a určeny • pro nástroje pracující s těmito soubory před vlastním spuštěním programu, například nástroje připravující instalaci, • zpracování za běhu programu. • Začínají znakem „@“. • Vyskytují se za řádkem s deklarací (tříd, metod, atributů, …) • Podobnou práci konají typové modifikátory. • Jsou určeny pro pokročilejší uživatele. • Někdy je automaticky vygeneruje vývojové prostředí.
Anotace Java API • @Deprecated (odmítaný, zavrhovaný) • Označení zastaralých nebo nebezpečných konstrukcí, které například musí být zachovány v knihovně tříd kvůli zpětné kompatibilitě. • Použijeme-li ji, měli bychom v dokumentačním komentáři použít značku @deprecated a za ní vysvětlit, proč je určitá konstrukce zavržena. • @Override (překrytí) • Je-li uvedena před metodami, které se mají při dědění překrýt, překladač upozorní na chyby v identifikátorech dědících metod. • @SupressWarnings (potlačení varování) • Při překladu by mělo být vždy zapnuté to, že překladač zobrazí všechna varovná hlášení. • přepínač -Xlint:all překladače javac • Vývojová prostředí umožňují vypnout určité druhy varování, ale lepší je možnost vypnout varování pro konkrétní úsek kódu, což je účel anotace @SupressWarnings. • Když například ve větvích konstrukce switch máme důvod nepoužívat příkaz break, použijeme anotaci @SupressWarnings("fallthrough"). • Názvy jednotlivých varování závisí na překladači, takže nejdříve si přečteme varování vypsané překladačem a potom jej použijeme jako argument anotace. • Pokud chceme potlačit výpis více varovných hlášení najednou, zadávají se jejich názvy oddělené mezerami do jednoho textového řetězce, například @SupressWarnings("fallthrough serial").
Základní (jednoduché, primitivní) datové typy • Vše v jazyce Java je buďto objekt nebo třída nebo součást objektu nebo třídy. • Protože základní datové typy nejsou z pohledu Javy objekty, dává Java k dispozici ke každému základnímu datovému typu i jeho wrapper class (obalující třídu), která začíná na velké počátečním písmeno. • Java na rozdíl od jazyka C definuje u každého typu jeho velikost. • Základní datové typy se dělí na celočíselné, znakové, řetězcové, logické, reálné a prázdný datový typ void, který se používá jen u metod.
Celočíselné typy a jejich konstanty • Jsou pouze znaménkové ve dvojkovém doplňku. • Mohou být zapsány ve třech číselných soustavách: • desítkové – Číslo nesmí začínat nulou. • osmičkové – Číslo začíná nulou. • šestnáctkové – Číslo začíná 0x nebo 0X • Dodržujeme styl 0xCD, nikoliv 0XCD, 0Xcd nebo 0xCd. • Konstanty jsou implicitně typu int. • Potřebujeme-li inicializovat typ long konstantou, použijeme na jejím konci znak „L“ (nebo „l“). • Například long k = 1234567890123L; • Jinak překladač hlásí chybu Integer literal out of range nebo dokonce odřízne nejvyšší bity. • Inicializace typu byte konstantou v rozsahu typu byte (-128 až +127) je v pořádku. • Například byte b = 123; • Jinak překladač hlásí chybu Incompatible type.
Znakový typ a jeho konstanty • Je pouze jeden – char – a má velikost 2 byty. • Je to z toho důvodu, že Java vnitřně pracuje se znaky ve znakové sadě Unicode. • Unicode se od té doby rozšířilo na znaky zabírající více než 2 byty (supplementary characters). Tyto znaky jsou reprezentovány jako posloupnost 2 znaků typu char. Tato dvojice znaků uložená společně do jedné hodnoty datového typu int se nazývá kódový bod (code point). • Chceme-li získat ze znaku jeho kódový bod, lze použít přetypování na int: int i = (int) 'A'; • Znakové konstanty jsou vždy uzavřeny do apostrofů a mohou být představovány: • jedním ASCII znakem, například 'A', '1', '%' • posloupností '\uXXXX', kde XXXX jsou šestnáctkové číslice. • Tento zápis se používá v případě akcentovaných znaků. • Například „č“ se zapíše jako '\u010D', viz mapa Unicode – Latin Extended-A. • Aby se zdrojový kód chybně nekonvertoval v prostředích s různým kódováním, je nutné toto kódování využívat. • Může být také součástí identifikátorů, • například int po\u010Det; // identifikátor počet • escape sekvencí • Místo '\a' (písknutí – alert) použijeme posloupnost '\0007'. (bell) • Písknutí vykoná zvuková karta (pokud ji počítač má), nikoli speaker, jako tomu je v jazyce C. • Nesmí být součástí identifikátorů. • osmičkovým zápisem • Vždy jsou nutné všechny tři osmičkové číslice, například '\007' je alternativní způsob zápisu písknutí.
Řetězcové konstanty • Datový typ String je posloupností hodnot typu char uzavřenou do uvozovek. • Tisk řetězce "Program kon\u010D\u00ED!\n\007" způsobí vypsání Program končí! odřádkování a písknutí. • Java umožňuje automatické zřetězování dlouhých řetězcových konstant oddělených mezerami, tabelátory nebo novými řádkami, před kterými ale musí být znak „+“. "Takhle vypada " + "velmi " + "dlouhy retezec." • Pokud je jedním z operandů operátoru „+“ řetězec, všechny ostatní operandy jsou na řetězec konvertovány. • Výraz "abc" + 4 se vyhodnotí jako "abc4". • Výraz "xyz" + (2 + 2 == 4) se vyhodnotí jako "xyztrue" • Výraz 1 + "2.5" se vyhodnotí jako "12.5"
Logický typ a jeho konstanty • Používá se typ boolean. • Reprezentuje jeden bit informace, ale velikost, kterou zabírá, není přesně definována. • Může nabývat pouze dvou hodnot true (logická 1), false (logická 0). • Logický typ je nepřevoditelný na celočíselné typy a naopak. Potřebujeme-li tuto operaci, je vhodné použít například: b = (i != 0); // převod hodnoty int na boolean i = (b) ? 1 : 0; // převod hodnoty boolean na int
Reálné typy a jejich konstanty • Java rozeznává typy float a double vyhovující standardu IEEE 754. • Reálné konstanty se tvoří podle běžných zvyklostí, například 3.14, 15. , .84, 5e6, 7E23, -7E+23, -7E-23 • Konstanty jsou implicitně typu double. • Potřebujeme-li inicializovat typ float konstantou, použijeme na jejím konci znak „F“ (nebo „f“). • Například float f = 3.14F;
Speciální hodnoty datových typů • Maximální a minimální hodnoty celočíselných i reálných typů lze získat pomocí konstant MIN_VALUE a MAX_VALUE, před které se dá ještě jméno příslušné třídy – Byte, Short, Integer, Long, Float, Double. • Například minimální hodnotu typů int a float získáme takto: int i = Integer.MIN_VALUE; float f = Float.MIN_VALUE; • Nenormální hodnoty typů float a double • Pokud dělíme kladné či záporné číslo nulou, získáme POSITIVE_INFINITY či NEGATIVE_INFINITY, které je nutné testovat metodou isInfinite(). if (Float.isInfinite(f) == true) • Pokud dělíme nulu nulou, získáme NaN, kterou je nutné testovat metodou isNaN(). if (Double.isNaN(d) == true)
Deklarace proměnných • Překladač nedovolí použít hodnotu neinicializované proměnné. • Neexistují globální proměnné, tedy proměnné, které „patří“ celému programu. V Javě každá proměnná patří buď třídě nebo instanci nebo metodě (funkci). • Každá proměnná by měla být deklarována na samostatné řádce a okomentována. int celkovyPlat; // celkový plat • Proměnné by měly být deklarovány na začátku metody a odděleny od příkazů prázdnou řádkou.
Deklarace proměnných s konstantní hodnotou • Tyto proměnné se běžně označují jako konstanty a deklarují se jako normální proměnné, ale navíc se použije klíčové slovo final. • Tak lze deklarovat konstantu dvěma způsoby: final int MAX = 10; • Konstantě MAX nelze znovu přiřadit jinou ani stejnou hodnotu. • nebo final int MAX; // prázdná konstanta (blank final) … // nějaký kód MAX = 10; // inicializace, po které se již hodnota nedá změnit • Tento způsob by se měl používat jen v odůvodněných případech. Jeden z těchto důvodů je použití ve statickém inicializačním bloku. • Skutečné konstanty, které se dají použít i mimo třídu, musí být deklarovány vně jakékoliv metody takto: public class TridaSKonstantou { public static final int MAX = 10; …} • Pak může být kdykoliv použita ve své třídě pod jménem MAX a mimo třídu pod takzvaným plně kvalifikovaným jménemTridaSKonstantou.MAX. • Tím je zabráněno konfliktu jmen konstant, což se v jazyce C často stávalo při použití konstant vzniklých pomocí #define.
Deklarace výčtového typu enum • Výčtový typ je výhodný v případech, kdy • pojmenované konstanty spolu souvisejí, • chceme mít jistotu, že se použijí jen vyjmenované hodnoty a nic navíc, • konstant je omezený počet (zhruba do 15), • seznam konstant je za běhu programu neměnný. • Typickým příkladem jsou dny v týdnu, názvy měsíců, pracovní zařazení, karty, směry, položky menu nebo rozbalovacího seznamu, argumenty programu s příkazovou řádkou. enum Okraj { HORNI, PRAVY, SPODNI, LEVY }; • Typ enum je součástí Javy od JDK 1.5 a poskytuje mnohem víc možností než v jazyce C. • Oracle, DevDaily, MindProd, Wakaleo 1, 2, singleton
Operátor přiřazení • Stejně jako v jazyce C je přiřazení výraz a jeho hodnotou je hodnota přiřazená levé straně. • Tudíž je možné jej používat v podmínkách, kde se však může zaměnit za operátor porovnání „==“. • Java na rozdíl od C chyby typu if (j = 5) hlásí jako chybu, protože očekává výraz typu boolean a dostává hodnotu“ typu int. • Základní operátor přiřazení je „=“. • Rozšířené operátory přiřazení jsou typu „+=“.
Explicitní typová konverze • Operátor konverze se zapisuje ve formě kulatých závorek, uvnitř kterých je jméno datového typu, na který chceme přetypovat, například: char c1 = 'á'; char c2 = (char) (c1 + 1); • následující znak v tabulce • Přetypování má nejvyšší prioritu. Pokud přetypováváme výraz, je nutné jej uzavřít do závorek, jinak bude přetypován pouze první člen výrazu. • Nutno provést v případě zužující konverze. • Převádíme na typ s menším rozsahem.
Implicitní typová konverze • Překladač sám provede konverzi, když přiřazujeme do typu s větším rozsahem. • Je to případ takzvané rozšiřující konverze. int j, i = 1234567890; float f; f = i; // implicitní rozšiřující konverze j = (int) f; // explicitní zužující konverze • Při konverzi na float či double může dojít ke ztrátě přesnosti, proto nesmíme výsledek porovnávat s určitou hodnotou ale testovat, zda je absolutní hodnota odchylky výsledku od hodnoty menší než nějaká malá konstanta. • Pořadí datových typů dle rozsahu od nejširšího po neužší: • double, float, long, int, short, byte
Aritmetické výrazy • Výraz ukončený středníkem se stává příkazem. • Aritmetické výrazy jsou tvořeny třemi druhy operátorů dle počtu operandů: • unární • unární „+“ a „-“, například j = -i; • prefix a postfix inkrement „++“ a dekrement „--“ • binární • sčítání „+“, odčítání „-“, násobení „*“ • Stejně jako jazyk C Java nehlásí přetečení a podtečení! • dělení „/“ • Jsou-li oba operandy celočíselné • je dělení celočíselné, • Java hlásí chybu při dělení nulou. • zbytek po celočíselném dělení (modulus) „%“ • ternární • alternativa k příkazu if – else
Relační operátory • Vytvářejí se z nich booleovské výrazy pro řízení běhu programu. • Stejné jako v jazyce C: • rovnost „==“, nerovnost „!=“, negace „!“, • menší „<“, menší nebo rovno „<=“, • větší „>“, větší nebo rovno „>=“, • logický součin – AND „&&“, logický součet – OR „||“ • Pro urychlení programu je vhodné dávat na první místo (doleva) ten výraz, jehož hodnota je • u operátoru && nejpravděpodobnější nepravda (false), • u operátoru || nejpravděpodobnější pravda (true). • Úplné vyhodnocování logických výrazů • logický součin „&“, logický součet „|“ • Využívá se v případě výrazů s vedlejšími účinky, které musí být vždy provedeny, například if (i == 2 & ++j == 3)
Bitové operace • Manipulují s jednotlivými bity čísla. • Stejně jako v jazyce C argumenty bitových operací nesmějí být proměnné typů float a double. • bitový součin „&“, bitový součet „|“ • Dle typu operandů Java pozná, zda jde o bitový součin nebo o úplné vyhodnocování logického výrazu. • Bitový exklusivní součet – XOR „^“ • Znaménkový posun doleva „<<“ a doprava „>>“ • Při posunu doprava se zachovává znaménkový bit. • Znaménkový bitový posun doprava se používá se pro rychlé dělení mocninou čísla 2 se zachováním znaménka. • Na rozdíl od jazyka C je znaménkové chování v definici jazyka Java. V jazyce C je implementačně závislé. • Neznaménkový posun doprava „>>>“ • Při posunu doprava se nezachovává znaménkový bit. • Správně funguje jen pro typy int a long. • Jedničkový doplněk – negace „~“ • unární operátor
Precedence operátorů • V definici jazyka Java tabulka priorit operátorů není, protože je definována gramatikou jazyka. • Různé zdroje uvádějí tabulky, které se v nepříliš podstatných detailech liší. • Z důvodu bezpečnosti a zvýšení srozumitelnosti kódu se doporučuje v hojné míře používat závorky.
Terminálový vstup a výstup • Ve skutečných programech jsou mnohem vhodnější grafická uživatelská rozhraní. • Program s terminálovým V/V není 100% přenositelný na všechny platformy, protože některé operační systémy vůbec terminálový V/V nemají. • Nebudeme používat třídu java.io.Console, protože neumí pracovat se soubory.
Metoda System.out.print() • Převede proměnnou, která je jejím parametrem, na řetězec představující dekadickou hodnotu proměnné a ten vytiskne. • Parametrem může být i řetězcová konstanta i = 4; j = 7; System.out.print(i + " + " + j + " = " + (i + j) + "\n"); • Vypíše i + j = 11 a odřádkuje. • Pokud by místo "\n" bylo '\n', znak '\n' se konvertuje na řetězec "\n", ale pouze, pokud je tam nějaký řetězec, viz poslední příklad. System.out.println(i + " + " + j + " = " + i + j); • Vypíše i + j = 47 a odřádkuje. • Metoda println() je pro odřádkování lepší než použití řetězce "\n". System.out.println("Pracovali na 100 %."); • Znak % není při výpisu nutné nijak zdvojovat. System.out.println("Toto je \"backslash\": '\\'."); • Znak \ se zdvojuje, uvozovky " musí předcházet znak \, • Apostrof ' se tiskne jako normální znak. System.out.print(i + '\n'); • Vypíše 14 a neodřádkuje, protože se sečetla hodnota i, což je 4, s kódem znaku '\n', což je 10, a výsledek se převedl na řetězec. char c = 'A'; System.out.println("Znak " + c + " má ASCII hodnotu " + (int) c); • Chceme-li při tisku změnit typ proměnné, můžeme použít přetypování. System.out.print("\b\b \n"); • Dva znaky „návrat kurzoru“, mezera, nový řádek • Za posledním prvkem generovaným cyklem se umaže oddělovač. • Nefunguje to při přesměrování výstupu do souboru
Metoda System.out.format() • Je součástí Javy od JDK 1.5 a je navázána na třídu java.util.Formatter. • Pod odkazem je dokumentace z Java API s možnými parametry. • Přebírá všechny formátovací možnosti funkce printf() z jazyka C a v mnoha místech je velmi elegantně rozšiřuje. • Kromě ní existuje i metoda System.out.printf(), která se však nedá využít pro tvorbu GUI. • Ve třídě String existuje statická metoda format() vracející typ String, využitelná při tvorbě GUI, která má stejná pravidla jako metoda System.out.format(). • Prvním parametrem musí být formátovací řetězec a za ním musí být tolik parametrů, kolik je ve formátovací řetězci znaků %, které neuvádějí escape sekvenci %n. • Konec řádku • \n je v Unicode znak '\u000A', ale používat pouze \n. • %n konec řádků závislý na platformě • Zápis konce řádku do textového souboru
Metoda System.out.format()příklady • Základní příklad • System.out.format("i = %d, f = %f%n", i, f); • Vypíše i dekadicky a f jako reálné číslo a odřádkuje. • Výpis celého čísla v desítkové soustavě • zarovnání doprava doplněním mezer zleva "i = %7d" • zarovnání doleva doplněním mezer zprava "i = %-7d" • zarovnání doprava a výpis i s kladným znaménkem "i = %+7d" • zarovnání doprava doplněním nul "i = %07d" • vypsání s oddělovačem řádů závislým na lokalitě "i = %,7d" • V české lokalitě může být oddělovačem mezera ve formě znaku čtvrt čtverčíku, který není v každém fontu, a potom se může vytisknout nesmyslný znak. • Výpis celého čísla v jiných soustavách • výpis v osmičkové soustavě "i = %o" • výpis v šestnáctkové soustavě "i = %x" nebo "i = %X" • Výpis znaku • System.out.format("Znak %c má ASCII hodnotu %d%n", c, (int) c); // přetypování je nutné • Výpis reálného čísla typu float nebo double • běžným způsobem "f = %f" • V české lokalitě je desetinným oddělovačem čárka. • běžným způsobem s desetinným oddělovačem tečka "f = %g" • Čísla s vysokým počtem míst budou zaokrouhlena nebo vypsána v semilogaritmickém tvaru. • v semilogaritmickém tvaru "f = %e" • s určitým počtem míst celkem a za desetinným oddělovačem "f = %7.2f" • se zarovnáním a oddělovačem řádů "f = %-,7.2f" • Výpis řetězce • velkými písmeny (funguje i pro akcentované znaky) "s = %S" (malými písmeny "s = %s")
Formátovaný vstup • Od JDK 1.5 lze používat třídu java.util.Scanner. import java.util.Scanner; // import třídy z knihovny import java.util.Locale; // import třídy z knihovny // předchozí 2 řádky je možné nahradit příkazem import java.util.*; public class Nacitani { public static void main(String[] args) { Scanner sc = new Scanner(System.in); // inicializace čtení sc.useLocale(Locale.US); // Desetinný oddělovač bude tečka. int i = sc.nextInt(); // metoda pro čtení celého čísla double d = sc.nextDouble(); // metoda pro čtení reálného čísla char c = sc.nextLine().charAt(0); // Zde dojde k běhové chybě. /* Musíme přečíst celou řádku a vyseparovat první znak. */ String s1 = sc.next(); // načtení řetězce do prvního bílého znaku /* Pokud řetězec začíná na bílé znaky, tak jsou zahozeny. */ String s2 = sc.nextLine(); // načtení celého řádku /* Znak(y) konce řádku jsou přečteny ale zahozeny. */ } } • Proč jsme nemuseli nic importovat při použití metody System.out.format? • Protože patří do balíku java.lang, který je importován vždy implicitně.
Problém vyprázdnění vstupu • Po každém čtení pomocí metod nextInt(), nextDouble() a next() je třeba pomocí volání metody nextLine() vyprázdnit buffer klávesnice příkazem sc.nextLine();
Řídící struktury • Budou probrány pouze odlišnosti od jazyka C. • Zásady formátování jsou stejné jako u jazyka C.
Podmínka: příkaz if – else • V závorce za if musí být výraz s výslednou hodnotou typu boolean. • Z tohoto důvodu není možné napsat častou céčkovskou chybu se zapomenutými závorkami kolem přiřazení. if (c = ctiZnak() != 'A') // syntaktická chyba if ((c = ctiZnak()) != 'A') // správně • Podmíněný výraz – ternární operátor • Umožňuje psát kratší programy for (int i = 1; i <= 100; i++) System.out.print(i + ((i % 10 == 0) ? "\n" : " ")); • Za každým desátým číslem bude odřádkováno.
Skoky • Java nezná příkaz goto, i když je goto rezervované slovo. • Příkazy break a continue společně s aparátem pro zachycení výjimek jej dostatečně a hlavně bezpečněji nahrazují. • Příkazy break a continue mají verzi s návěštím a bez návěští. • Příkaz break (na rozdíl od continue) ukončuje také právě prováděný blok, ve kterém nemusí být žádný cyklus, nebo příkaz switch.
Příkaz while a do – while • V závorce s ukončovací podmínkou musí být výraz s výslednou hodnotou typu boolean. while (1) // syntaktická chyba • Cyklus s ukončující podmínkou public static void main(String[] args) { Scanner sc = new Scanner(System.in); char c; while ((c = sc.nextLine().charAt(0)) != 'z') { if (c >= 'a') System.out.print(c); } System.out.println("\nCteni znaku bylo ukonceno."); } • Nekonečný cyklus ukončený skokem bez návěští public static void main(String[] args) { Scanner sc = new Scanner(System.in); char c; while (true) { // nekonečná smyčka if ((c = sc.nextLine().charAt(0)) < 'a') continue; // zahození velkých písmen atd. if (c == 'z') break; // zastavení po načtení znaku 'z' System.out.print(c); // tisk znaku } System.out.println("\nCteni znaku bylo ukonceno."); }
Příkaz for • V Javě se velmi často deklaruje řídící proměnná cyklu přímo v hlavičce cyklu. for (int i = 1; i <= 10; i++) System.out.println(i); • V jazyce C je to dovoleno počínaje normou C99, ale ne všechny nové překladače to dovolují, takže se to nedoporučuje. • Java nezná operátor čárka, pokud není v inicializační nebo v iterační části for cyklu. • Správné použití int i, faktorial; for (i = 1, faktorial = 1; i <= 5; i++) faktorial *= i; • Nesprávné použití for (int i = 1, faktorial = 1; i <= 5; i++) faktorial *= i; • Proměnná faktorial má oblast platnosti pouze v cyklu for. • Například po následném příkazu System.out.println(faktorial); nastane chyba překladu. • Má ještě jednu variantu zvanou „for-each“, která se užívá při práci s poli, typem enum a kontejnerem objektů.
Příkaz for s příkazem continue s návěštím • Výpis indexů matice pod hlavní diagonálou navesti: for (int n = 0; n < 4; n++) { for (int m = 0; m < 4; m++) { if (m == n) { System.out.println(); continue navesti; } System.out.print(m + "-" + n + " "); } }
Příkaz for s příkazem break s návěštím • Výskok z vnořených (zahnízděných) cyklů boolean jeChyba = false; chyba: { for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { for (int k = 0; k < 10; k++) { if (x[k] == 0) { jeChyba = true; break chyba; } a[i][j][k] = a[i][j][k] + b[j] / x[k]; } } } System.out.println("Bez chyby."); } if (jeChyba) { System.out.println("Nulovy delitel!"); }
Příkaz switch • Počet větví je neomezen. • Dle ANSI C jich musí být alespoň 257. • Výraz, podle kterého se rozhoduje, musí být pouze typu char, byte, short nebo int. • Nesmí být typu long, float, nebo double. • Větve končí příkazem break nebo dojde k vykonání příkazů v další větvi. • Viz anotace @SupressWarnings("fallthrough"). • Příkaz continue s příkazem switch nespolupracuje. • Pokud by byl příkaz switch vnořen do while cyklu, skočí příkaz continue na konec tohoto while cyklu a potom se bude while cyklus opakovat, ale je to nepřehledné.
Příkaz return • Příkaz return ukončí provádění metody (funkce), která jej obsahuje. • V metodě main() ukončí příkaz return celý program. • Často se pomocí return vrací nějaká hodnota, jejíž typ záleží na typu metody. • Metoda System.exit() ukončí bezprostředně program bez návratu do funkce volající. • Používá se jen v aplikacích, nikoliv v apletech.
Metody • Metoda je v OOP termín pro podprogram neboli funkci. • Metody v Javě se dělí na • metody třídy neboli statické metody a • metody instance. • Zatím se budeme věnovat pouze společným znakům obou podskupin metod. • Tyto společné znaky budou vysvětlovány na statických metodách, aby bylo možné ověřit popisované skutečnosti bez nutnosti použití objektů.
Oblast řešená metodou • Překladač neomezuje délku názvu metody a délku jejího kódu. • Je však vhodné psát takové metody, které provádějí pouze jednu činnost dobře vystiženou názvem metody. • Délka těla metody by neměla přesáhnout cca 20 řádek. • Jméno metody by mělo být krátké a výstižné, viz identifikátory. • Pokud nejsme schopni přiřadit metodě rozumné krátké jméno, je to pravděpodobně tím, že se snažíme, aby prováděla více než jednu činnost. To svědčí o špatné dekompozici problému.
Deklarace metody • Deklarace metody zahrnuje • hlavičku metody, tj. jméno metody, • Není ukončena středníkem. • Levá složená závorka je na téže řádce a je oddělena jednou mezerou. • typ návratové hodnoty, • Nemůže být vynechán. • případně i typy a jména formálních parametrů, • tělo, ve kterém je uložen kód metody. • V Javě nevadí, je-li deklarace metody až za místem volání metody. Není tedy nutné uvádět funkční prototypy. • Každá metoda musí patřit do nějaké třídy. • Podle jména této třídy se musí jmenovat i soubor, ve kterém je uložena.
Příklad metody s parametry • deklarace statické metody static int max(int a, int b) { if (a > b) return (a); // možno také return a; else return (b); } • volání statické metody uvnitř jedné třídy x = max(10 * i, j - 15);
Metoda bez parametrů • příklad metody, která přečte dvě celá čísla z klávesnice a vrátí jejich součet static int nactiASecti() { Scanner sc = new Scanner(System.in); int a, b; a = sc.nextInt(); b = sc.nextInt(); return (a + b); } • volání metody j = nactiASecti(); • Chybné volání metody j = nactiASecti; bez závorky je syntaktickou chybou. • Překladač vypíše chybu Variable nactiASecti not found in class. • Není možné uvést místo neexistujících formálních parametrů klíčové slovo void, např. static int nactiASecti(void) { • Překladač hlásí chybu <identifier> expected.
Metoda bez návratového typu • Jejím návratovým typem je void. • Příkaz return se v ní používá pouze pro nucené ukončení metody před dosažením jejího konce po nějaké podmínce. • procedura s parametry static void tiskPenez(int koruny) { System.out.println("Cena: " + koruny + " Kc"); } • volání metody tiskPenez(a + b); • procedura bez parametrů static void tisk() { System.out.println("Ahoj"); } • volání metody tisk();