Co je to Generics v Javě?

Generics v Javě byl představen v roce 2004 jako nová funkce programovacího jazyka Java a byl součástí vydání JDK 5. Nejčastěji se používá spolu s rámcem kolekcí Java. Od dnešního dne je to jedna z nejvýznamnějších a nejvyhledávanějších funkcí programovacího jazyka Java.

Generickou Javu našli čtyři jedinci, jmenovitě Gilad Bracha, Martin Oderský, David Stoutamire a Philip Wadler v roce 1998. Bylo to rozšíření jazyka Java, které podporovalo generické typy. Účelem bylo dosáhnout dvou hlavních cílů, kterými jsou:

  1. Typ bezpečnosti
  2. Opětovné použití kódu

Definice generik v Javě

Generika lze definovat jako způsob, jak dosáhnout opětovného použití kódu definováním obecných tříd, rozhraní, konstruktérů a metod, které lze použít s různými datovými typy, a také dosáhnout bezpečnosti typu deklarováním datového typu, který se používá při implementaci předem, čímž se eliminuje šance na chybu za běhu.

Jak jsou generika implementována v Javě?

Generika jsou implementována pomocí hranatých závorek „“. V závorkách jsou v nich obsaženy parametry typu „T“. Příklad, . Parametr typu „T“ je zástupný symbol místa, který označuje, že datovému typu bude přiřazen v době spuštění. Například obecná třída bude definována jako:

public class MyGenericClass (…)

Parametry standardního typu jsou následující:

  • T: Typ
  • E: Prvek
  • N: Číslo
  • K: Klíč
  • V: Hodnota

S, U, V atd. Se používají k definování druhého, třetího a čtvrtého parametru v případě, že se používají víceparametrové parametry.

Porozumění generikům v Javě

Nyní by vás mohlo zajímat, co je typová bezpečnost a jak to funguje? Nebo jak se liší obecné třídy, rozhraní, konstruktéři a metody od našich běžných tříd a metod, díky nimž jsou znovu použitelné? Pojďme to zjistit.

Java, která je staticky psaným jazykem, vyžaduje, abyste před použitím deklarovali „typ“, který je datovým typem hodnoty, kterou proměnná drží.

Příklad: String myString =”eduCBA”;

Zde je „String“ datový typ, „myString“ je proměnná, která bude obsahovat hodnotu, jejíž typ je String.

Nyní, pokud se pokusíte předat booleovskou hodnotu namísto řetězce, například:

String myBooleanStr = true;

Okamžitě se zobrazí chyba kompilace s hlášením „Neshoda typu: nelze převést z booleovského řetězce na řetězec“.

Jak dosáhneme opakovatelnosti kódu u generik?

Nyní definujme běžnou metodu:

public static void welcome(String name)(
System.out.println("welcome to " + name);
)

Tuto metodu lze vyvolat pouze předáním parametru řetězce. Například:

welcome(“eduCBA”);

Jeho výstup bude „vítán pro eduCBA“.

Tuto metodu však nemůžete vyvolat vynecháním jiných typů dat, jako je celé číslo nebo booleovské číslo. Pokud se o to pokusíte, budete vyzváni k chybě při kompilaci s uvedením „Metoda welcome (String) typu Runner není použitelná pro argumenty (booleovské)“. To znamená, že nelze předat jiný typ dat metodě, která jako parametr přijímá pouze řetězec.

To také znamená, pokud si přejete vyvolat podobnou metodu pro jiný datový typ, pak budete muset napsat novou metodu, která akceptuje požadovaný datový typ jako parametr. Tato vlastnost metod přepisování s parametry různých datových typů je známá také jako přetížení metody. Hlavní nevýhoda tohoto je to zvětší velikost vašeho kódu.

Mohli bychom však také použít Generics k přepsání výše uvedené metody a použít ji pro jakýkoli požadovaný typ dat.

Definování obecné metody:

public static void welcome(T t)(
System.out.println("it is " + t);
)

Poznámka : Zde „t“ je objekt typu T. T bude přiřazen datový typ, který se používá k vyvolání metody.

Nyní můžete tuto metodu znovu použít tak, že ji v případě potřeby vyvoláte pro řetězec nebo pro booleovské číslo nebo celé číslo nebo jakýkoli jiný typ dat.

welcome("educate");
Integer Myint = 1;
welcome(Myint)
welcome(true);

Výše uvedené příkazy poskytnou níže uvedený výstup:

Je to Educa
Je to 1
To je pravda

Použitím generik zde tedy můžeme znovu použít naši metodu pro různé typy dat.

Jak dosáhnout bezpečnosti typu pomocí generik?

Jeden z hlavních rozdílů mezi poli a sbírkou je, že pole mohou ukládat pouze homogenní data, zatímco kolekce mohou ukládat heterogenní data. To znamená, že kolekce mohou ukládat libovolný uživatelem definovaný datový typ / objekty.

POZNÁMKA: Kolekce může obsahovat pouze objekty (typ dat definovaný uživatelem), nikoli primitivní typ dat. Aby bylo možné pracovat s primitivními daty, kolekce typů využívají třídy obálky.

Nyní uvažme ArrayList.

ArrayList myList = new ArrayList();

K objektu ArrayList přidáme data typu String, Integer a Double.

myList.add("eduCBA");
myList.add(1);
myList.add(5.2);

Při tisku objektu ArrayList vidíme, že obsahuje následující hodnoty: (eduCBA, 1, 5.2).

Nyní, pokud si přejete tyto hodnoty načíst do proměnných, budete je muset přepsat.

String someStr = (String)myList.get(0);
Integer someInt = (Integer)myList.get(1);
Double someFlt = (Double)myList.get(2);

V případě, že nemáte typcast, budete vyzváni k chybě při kompilaci s uvedením „Neshoda typu: nelze převést z objektu na řetězec“.

Z toho můžete usoudit, že při načítání objektů z vašeho ArrayListu je třeba je přetypovat na jejich příslušné typy. Otázka, která zde vyvstává, je, jak budete vědět, na jaký typ dat se má typcast použít? V reálném čase bude váš ArrayList obsahovat tisíce záznamů a typcasting na různé datové typy pro každý jednotlivý objekt nebude možné. Můžete skončit typcasting na nesprávný datový typ. Co se stane potom?

Tentokrát nedostanete chybu kompilace, ale vyvoláte runtime chybu s uvedením „Výjimka v podprocesu„ main “java.lang.ClassCastException: java.lang.Integer nelze odevzdat do java.lang.String na com.serviceClasess.Runner .main (Runner.java:43) “.

Protože nemůžeme zaručit typ dat přítomných v kolekci (v tomto případě ArrayList), nejsou považována za bezpečná vzhledem k typu. Zde přicházejí do hry generici, aby zajistili bezpečnost typu.

Použití ArrayList s generiky:

ArrayList myList = new ArrayList();

Všimněte si, že uvnitř hranatých závorek „“ je specifikován typ String, což znamená, že tato konkrétní implementace ArrayList může obsahovat pouze data typu String. Pokud se k němu pokusíte přidat jakýkoli jiný typ dat, jednoduše zahodí chybu kompilace času. Zde jste zabezpečili typ ArrayList tak, že jste vyloučili jeho šanci přidat jiný typ dat než „String“.

Nyní, když jste určili typ dat, který je možné přidat do vaší sbírky pomocí generik, již jej nemusíte při načítání dat psát. To znamená, že můžete jednoduše načíst svá data písemně:

String someStr = myList.get(0);

Jak Generics v Javě usnadňuje práci?

Pomáhá zajistit, aby vaše kolekce byly typově bezpečné, a tak se ujistí, že váš kód neuspěje později kvůli výjimce doby běhu. To také šetří kodér od nutnosti psát každý objekt v kolekci, čímž se vývoj kódu zrychlí a usnadní. Použitím obecných tříd a metod lze během implementace kód znovu použít podle požadovaných typů dat.

Co jiného můžete dělat s Generics v Javě?

Dosud jsme viděli, jak můžeme dosáhnout druhové bezpečnosti a opakovaného použití kódu s generiky. Nyní se podívejme na další funkce, které generici nabízejí. Oni jsou:

  1. Ohraničené a více ohraničené typy
  2. Zadejte zástupné znaky

Ohraničený typ: V případě omezeného typu je datový typ parametru omezen na určitý rozsah. Toho je dosaženo pomocí klíčového slova „rozšiřuje“.

Uvažujme například obecnou třídu s parametrem omezeného typu, který rozšiřuje rozhraní Runnable:

class myGenericClass()

Nyní při vytváření objektu v jiné třídě:

myGenericClass myGen = new myGenericClass();

Výše uvedený příkaz se dokonale spustí bez jakýchkoli chyb. To je v případě omezeného typu, můžete předat stejný typ třídy nebo její podřízený typ třídy. Také můžete svázat typ parametru s rozhraním a předat jeho implementace při jeho vyvolání, jako v našem příkladu výše.

Co se stane, pokud se pokusíte použít jiný typ parametru?

myGenericClass myGen = new myGenericClass();

Ve výše uvedeném případě obdržíte chybu kompilace s uvedením „Vázaná neshoda: Typ Integer není platnou náhradou za typcast typu myGenericClass“.

Více ohraničených typů: V případě více ohraničených typů můžeme dát datový typ parametru svázat s více než jedním typem. Například,

Class myGeneric()

V takovém případě můžete předat jakýkoli typ, který rozšiřuje třídu Number a implementuje rozhraní Runnable. Při použití více omezených typů je však třeba poznamenat několik věcí:

  1. Nemůžeme rozšířit více než jednu třídu najednou.
  2. Můžeme rozšířit libovolný počet rozhraní najednou, což není omezení pro rozhraní.
  3. Název třídy by měl vždy nejprve následovat název rozhraní, pokud ne, bude mít za následek chybu kompilace.

Typ Zástupné znaky: Jsou reprezentovány symbolem „?“ - otazník. Využívá dvě hlavní klíčová slova:

se rozšiřuje (pro definování horní hranice) a super (pro definování dolní hranice).

Například,

ArrayList al

Tento objekt ArrayList „al“ obsahuje všechna data typu T a všechny jeho podtřídy.

ArrayList al

Tento objekt ArrayList „al“ bude obsahovat všechna data typu T a všechny jeho nadtřídy.

Výhody Generics v Javě

1. Flexibilita : Generics poskytuje našemu kódu flexibilitu pro přizpůsobení různých typů dat pomocí generických tříd a metod.

2. Údržba a opakovaná použitelnost kódu : Vzhledem k obecným třídám a metodám není nutné kód znovu přepisovat, v případě změny požadavků v pozdějším stadiu, což usnadňuje údržbu a opětovné použití kódu.

3. Bezpečnost typu: Poskytuje zabezpečení typu pro rámec sběru definováním datového typu, který může sbírka předem mít, a vylučuje jakékoli šance na selhání v době běhu v důsledku ClassCastException.

4. Eliminace potřeby typcastu: Vzhledem k tomu, že datové typy uchovávané ve sbírkách jsou již stanoveny, není nutné je v době načítání typcastovat. To snižuje délku kódu a také snižuje úsilí kodéru.

Obecné dovednosti v jazyce Java

Abyste mohli pracovat s Generics, měli byste se dobře orientovat se základy Java. Měli byste pochopit, jak funguje kontrola typu a odlévání typu. Je nezbytná důkladná znalost dalších konceptů, jako je přetížení metody, vztah mezi mateřskými a podřízenými třídami, rozhraní a jejich implementace. Také pochopení rozdílu mezi primitivními datovými typy (systémově definovaný datový typ) a objekty (uživatelem definovaným datovým typem) je zásadní, pokud jde o práci s rámcem kolekce.

Proč bychom měli používat Generics v Javě?

Díky použití generik je náš kód lépe udržovatelný, protože snižuje potřebu přepisovat kód specifický pro typ dat vždy, když dojde ke změně požadavku. Použitím genericky vázaného typu byste mohli omezit typ dat a zároveň poskytnout flexibilitu kódu definováním jeho rozsahu. Váš kód pravděpodobně později selže, protože poskytuje bezpečnost typu, takže váš kód je méně náchylný k chybám.

Rozsah pro generika v Javě

Rozsah generik je omezen na čas kompilace. To znamená, že generický koncept je použitelný pouze v době kompilace, ale nikoli v době běhu. Například,

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

ArrayList myList = new ArrayList();

Zde jsou všechna čtyři výše uvedená tvrzení stejná. Umožní přidání libovolného typu dat do objektu seznamu.

Závěr

Generics usnadňuje kódování pro kodér. To snižuje šance na setkání s ClassCastException za běhu tím, že poskytuje silnou kontrolu typu. Zcela eliminuje potřebu obsazení typu, což znamená, že je třeba napsat méně kódu. Poskytuje nám to možnost vyvinout obecné algoritmy, které jsou nezávislé na typu dat, se kterým pracují.

Doporučené články

Toto byl průvodce Co je Generics v Javě ?. Zde jsme diskutovali o dovednostech, rozsahu, práci, porozumění a výhodách generik v Javě. Další informace naleznete také v dalších navrhovaných článcích -

  1. Co je společné rozhraní brány
  2. Jak nainstalovat Java 8
  3. co je mýdlo
  4. Co je to JavaScript?
  5. Java Booleans

Kategorie: