1 z 8 Programovací jazyk Java Enumerace (výčty) Složitější definice výčtového typu Konstanty anonymních typů Výčtový typ a datové struktury Java packaging JAR archivy CLASSPATH Apache Ant 10. přednáška Obsah Enumerace (výčty) Enumerace jsou datový typ definující symbolická jména a jejich hodnoty. Enumerace mohou nahrazovat konstanty (int, String), které nejsou typově bezpečné. Například: public class Obdobi { public static final int JARO = 0; public static final int LÉTO = 1; public static final int PODZIM = 2; public static final int ZIMA = 3; Enumerace se vytvářejí pro skupiny souvisejících konstant. Uvozují se klíčovým slovem enum. V nejjednodušší variantě může být enumerace definována pouhým výčtem hodnot: public enum Obdobi { JARO, LÉTO, PODZIM, ZIMA; Překladač skrytě vytvoří potomka třídy Enum, avšak nelze použít zápis public class Obdobi extends Enum {... Konstanty výčtových typů je možné používat nejenom k uchovávání hodnot a k jejich případnému porovnávání v příkazech if nebo while, ale je je možné použít také v příkazu switch a cyklu for: public class Jablon {
2 z 8 static Obdobi o; public static String cinnost(obdobi obdobi) { switch (obdobi) { case JARO: return "kvete"; case LÉTO: return "zraje"; case PODZIM: return "plodí"; case ZIMA: return "spí"; default: // Překladač nekontroluje, zda jsme vyčerpali všechny možnosti, a může se chybně // domnívat, že existuje ještě nějaká cesta, kterou jsme nepokryli. throw new IllegalArgumentException("Neočekávaná hodnota parametru období = " + obdobi); public static String vyjmenuj() { String s = ""; for (Obdobi obd : Obdobi.values()) { s += obd + " "; return s; public static void main(string[] args) { o = Obdobi.PODZIM; // Přístup ke konstantě je skrze název třídy. System.out.println(cinnost(o)); // Vypíše plodí System.out.println(o.name()); // Vypíše PODZIM System.out.println(o.ordinal()); // Vypíše 2 System.out.println(o.toString()); // Vypíše PODZIM ZIMA System.out.println(vyjmenuj()); // Vypíše JARO LÉTO PODZIM Přestože každá proměnná typu enumerace je referencí na objekt (typu enum), nevoláme při jejím vytvoření konstruktor. Každý výčtový typ dědí z třídy Enum několik metod. Enumerace jsou v Javě od verze 5. Složitější definice výčtového typu Výčtové typy mohou obsahovat i vlastní metody a definované konstanty mohou využívat
3 z 8 konstruktory s dalšími parametry. Podmínkou je, aby výčet konstant byl v enumeraci uveden jako první a výčet konstant byl zakončen středníkem. Všimněte si, jak jsou předávány parametry konstruktoru za definovanou konstantu se pouze vloží závorky a za ně se vypíší hodnoty předávaných parametrů: public enum Smer8 { VÝCHOD(1, 0, "S", "VYCHOD"), SEVEROVÝCHOD(1, -1, "SV", "SEVEROVYCHOD"), SEVER(0, -1, "S", "SEVER"), SEVEROZÁPAD(-1, -1, "SZ", "SEVEROZAPAD"), ZÁPAD(-1, 0, "Z", "ZAPAD"), JIHOZÁPAD(-1, 1, "JZ", "JIHOZAPAD"), JIH(0, 1, "J", "JIH"), JIHOVÝCHOD(1, 1, "JV", "JIHOVYCHOD"), ŽÁDNÝ(0, 0, "@", "ZADNY"); private int dx, dy; private String zkratkasmeru, smer; private Smer8(int dx, int dy, String zkratkasmeru, String smer) { this.dx = dx; this.dy = dy; this.zkratkasmeru = zkratkasmeru; this.smer = smer; public double delkaposunu() { return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); Ukázka použití: public class Posun { public static void main(string[] args) { Smer8 smer = Smer8.SEVER; System.out.println(smer.delkaPosunu()); // Vypíše 1 smer = Smer8.JIHOVÝCHOD; System.out.println(smer.delkaPosunu()); // Vypíše 1.4142135623730951 System.out.println(smer.name()); // Vypíše JIHOVÝCHOD System.out.println(smer.ordinal()); // Vypíše 7 System.out.println(smer.toString()); // Vypíše JIHOVÝCHOD. Tuto metodu lze (jako jednu z mála) v enumeraci překrýt. Jelikož každá proměnná typu enumerace je referencí na objekt (typu enum), můžeme přistupovat k jejím metodám a atributům.
4 z 8 Konstanty anonymních typů Někdy potřebujeme, aby instance výčtového typu nepředstavovaly datový, ale funkční objekt, tj. aby se jednotlivé instance lišily chováním svých metod. Příslušné metody pak uvedeme přímo u každé konstanty ve výčtu konstant. Výsledkem pak bude to, že jednotlivé instance výčtového typu budou různých typů. Budou se vzájemně lišit chováním svých metod, neboť se ve skutečnosti bude jednat o instance různých anonymních tříd. Příklad: public enum Operator { SOUČET('+') { return x + y;, ROZDÍL('-') { return x - y;, SOUČIN(' ') { return x * y;, PODÍL(':') { return x / y;, MOCNĚNÍ('^') { return Math.pow(x, y);, ODMOCNĚNÍ('\u221A') { //Znak pro odmocninu return Math.pow(y, 1 / x); ;
5 z 8 private final char znak; private Operator(char znak) { this.znak = znak; public String tostring() { return "" + znak; abstract double proved(double x, double y); Program public class VyzkousejOperator { public static void main(string[] args) { int x = 2, y = 10; for (Operator o : Operator.values()) { System.out.println(x + " " + o.tostring() + " " + y + " = " + o.proved(x, y)); for (Operator o : Operator.values()) { System.out.println(o.name() + " je konstantou třídy " + o.getdeclaringclass().getname() + ", ale instancí třídy " + o.getclass().getname()); pak vypíše: 2 + 10 = 12.0 2-10 = -8.0 2 10 = 20.0 2 : 10 = 0.2 2 ^ 10 = 1024.0 2 10 = 3.1622776601683795 SOUČET je konstantou třídy Operator, ale instancí třídy Operator$1 ROZDÍL je konstantou třídy Operator, ale instancí třídy Operator$2 SOUČIN je konstantou třídy Operator, ale instancí třídy Operator$3 PODÍL je konstantou třídy Operator, ale instancí třídy Operator$4 MOCNĚNÍ je konstantou třídy Operator, ale instancí třídy Operator$5 ODMOCNĚNÍ je konstantou třídy Operator, ale instancí třídy Operator$6 Výčtový typ a datové struktury Pokud chceme ukládat výčtový typ do množin či ho používat jako klíč v mapách (rozhraní
6 z 8 Map), poskytuje Java v balíčku java.util speciální rychlé implementace množiny a mapy třídy EnumSet a EnumMap. Třída EnumSet má navíc metodu range(), kterou lze použít pro procházení pouze části seznamu prvků ve výčtovém typu. V následujícím příkladu se vypíší pouze pracovní dny: public enum DenVTydnu { NEDELE, PONDELI, UTERY, STREDA, CTVRTEK, PATEK, SOBOTA... for (Den den : EnumSet.range(Den.PONDELI, Den.PATEK)) { System.out.println(den); Třída EnumSet dále podporuje některé základní operace s množinami výčtových typů. Další informace: Kolekce EnumMap a EnumSet. Java packaging JAR archivy Každý alespoň trochu složitější program má podobu několika tříd, příp. i rozhraní. Abychom při distribuci programu nemuseli kopírovat někdy i velké množství samostatných souborů, zabalíme je do jednoho archivu. Java na sbalení množiny souborů zdrojových i přeložených (.class) nabízí nástroj jar spustitelný z příkazové řádky (např. pro Windows je to jar.exe). Sbalením vznikne soubor (archiv).jar formátově podobný ZIPu (obvykle je to ZIP formát). Kromě souborů obsahuje i metainformace (tzv. MANIFEST). Jedná se o textový soubor MANIFEST.MF umístěný v adresáři META-INF. Chceme-li vytvořit spustitelný JAR archiv (aby šel spustit příkazem java.exe -jar), umístíme do manifestu řádek Main-Class: NázevSpouštěnéTřídy, např. Main-Class: svet.chovatelstvi.main. Obecně je manifest složen z řádků název_atributu: hodnota. Je-li nastaven atribut Main-Class, můžeme program spustit např. příkazem java -jar xyz.jar. Jinak musíme specifikovat třídu s metodou main: java -cp xyz.jar cz.main. Součástí archivu nemusí být jen.class soubory, ale i ialší zdroje, např. obrázky, zdrojové texty programu, dokumentace apod. Volby (přepínače) příkazu jar lze vypsat spuštěním jar bez parametrů. Ve vývojových prostředích (IDE) obvykle nalezneme příkaz k vytvoření JAR archivu v nabídce příkazů (např. v NetBeans pomocí klávesy F11; jar archiv se vytvoří v adresáři dist). CLASSPATH CLASSPATH prostor, kde se hledají class soubory. Class soubory mohou být umístěny v adresáři, nebo v JAR souboru.
7 z 8 Lze nastavit přes systémovou proměnou CLASSPATH nebo přes volbu (přepínač) -cp, -classpath u při spouštění JVM. Pokud není proměnné CLASSPATH uvedena, bere se aktuální adresář. Použití přepínače má přednost před systémovou proměnnou. Syntaxe nastavení systémové proměnné CLASSPATH ve Windows: set CLASSPATH=path1;path2... Syntaxe nastavení systémové proměnné CLASSPATH v Unixu/Linuxu: setenv CLASSPATH path1:path2... Příklady použití volby (přepínače) ve Windows a v Unixu/Linuxu. Situace: Spuštění programu: Další příklady použití volby (přepínače) ve Windows: java -classpath C:\java\MyClasses cz.main java -classpath C:\java\MyClasses\myclasses.jar cz.main java -classpath C:\java\MyClasses;C:\java\OtherClasses cz.main java -classpath C:\java\MyClasses;C:\java\OtherClasses;. cz.main Úvod: Apache Ant na Wikipedii Apache Ant Apache Ant jak na složité projekty: http://www.abclinuxu.cz/clanky/programovani /apache-ant-jak-na-slozite-projekty Snadno srozumitelný a o příklady doplněný úvod do používání mocného pomocníka programátora: http://www.abclinuxu.cz/clanky/recenze/apache-ant Web: http://ant.apache.org Viz zveřejněná prezentace Bc. Jana Kolomazníka.
8 z 8