Stejně jako každý ninja musí prokázat, že dokáže zabít i roličkou toaletního papíru, i já předvedu stupeň své nezměrné zvrhlosti tím, jak dokážu používat složené závorky. Složené závorky asi používáte všichni, ale všichni před ně určitě amatérsky píšete něco jako jméno třídy, metody, if, for nebo něco podobného. To já už jsem dosáhl vyšší úrovně zasvěcení a nepíšu před ně vůbec nic. Předem vás chci upozornit ať to doma radši nezkoušíte, předvedená technika vyžaduje léta tréninku, dřiny a odříkání.
První možností, kde se se závorkou bez ničeho můžete setkat, je inicializační blok. Vypadá to následovně.
public class UglyClass { { System.out.println("Ugly code"); } { System.out.println(" rocks :-/"); } }
Krása, že? Ano, opravdu tento kód je v Javě přípustný. Tyto bloky jsou zavolány pokaždé, když je třída instancována a to v pořadí, v jakém jsou uvedeny v kódu. Výhodou má být, že je tento kód sdílený mezi všemi konstruktory. Jenom tiše doufám, že to nikdo nepoužívá. Byla by to opravdu krásná past, schovat podobný blok někam na konec třídy a tam něco ošklivého provést. Dlouho jsem přemýšlel, jestli by existovalo nějaké rozumnější využití. Nebyl by to můj ohavně zvrhlý mozek, kdyby něco nevymyslel. Tady to máte:
List<Address> addresses = Arrays.asList( new Address() { { setStreet("Ugly 13"); setCity("Brno"); setZip("000000"); } }, new Address() { { setStreet("Ugly 15"); setCity("Brno"); setZip("000000"); } } );
Představte si, že chci nainicalizovat seznam adres (třeba v unit testu) a nemám vhodný konstruktor. Tak si vytvořím anonymního potomka a v jeho inicializačním bloku si nastavím co potřebuji. Cool.
Samozřejmě normální, konzervativní varianta je takováto:
List<Address> addresses = new ArrayList<Address>(2); Address address1 = new Address(); address1.setStreet("Ugly 13"); address1.setCity("Brno"); address1.setZip("000000"); addresses.add(address1); Address address2 = new Address(); address2.setStreet("Ugly 15"); address2.setCity("Brno"); address2.setZip("000000"); addresses.add(address1);
Nuda co? Navíc má tato varianta jeden velký problém. Často v ní udělám chybu. Jako třeba v uvedeném příkladě. Kdo si té chyby všiml rovnou, má bod, já bych ji tam hodně dlouho hledal.
Abych podobné chybě zabránil, mohu použít druhou možnost, jak napsat osamocené složené závorky. Prostě je fouknu doprostřed metody, čímž vytvořím normální blok kódu.
List<Address> addresses = new ArrayList<Address>(2); { Address address1 = new Address(); address1.setStreet("Ugly 13"); address1.setCity("Brno"); address1.setZip("000000"); addresses.add(address1); } { Address address2 = new Address(); address2.setStreet("Ugly 15"); address2.setCity("Brno"); address2.setZip("000000"); addresses.add(address2); }
Dosáhnu tím toho, že omezím platnost lokálních proměnných. Překladač mě pak nenechá do seznamu vložit stejnou adresu dvakrát. To už je použití, které by se možná i dalo obhájit.
A teď si představte, že člověku jako já, dáte do ruky closures (uzávěry). To by pak museli čtenáře mého kódu rovnou uzavřít do blázince. Aha, už alespoň vím, proč se closures jmenují, tak jak se jmenují.
Pokud máte opravdu silné nervy, podívejte se na tento článek, tam uvidíte, že já jsem v podstatě neškodný.