Middle
Ինչպե՞ս է Java-ն մշակում գեներիկները։
sobes.tech AI
Պատասխան AI-ից
Java-ն մշակվում է ընդհանուր տիպերի (generics) վերացման միջոցով (type erasure):
Կոմպիլյատորային ժամանակ, ընդհանուր տիպերի մասին տեղեկատվությունը հեռացվում է: Սա նշանակում է, որ ArrayList<String> և ArrayList<Integer> դասերի բայթկոդը նույնն է՝ ArrayList։ Փոխարինող տիպերի փոխարեն, կոմպիլյատորը տեղադրում է Object կամ սահմանափակված վերին սահմանափակումը։ Տիպերի օգտագործման վայրերում, կոմպիլյատորը ավելացնում է անորոշ վերածումներ (casts):
Տիպերի վերացման առավելությունները՝
- Համատեղելիություն ավելի վաղ Java տարբերակների հետ: Գումարային կոդը կարող է համագործակցել նրանցից առաջ գրված կոդի հետ, քանի որ բայթկոդը չի պարունակում տիպերի մասին տեղեկատվություն:
- Ավելորդ բեռների բացակայություն ժամանակի ընթացքում: Քանի որ ընդհանուր տիպերի մասին տեղեկատվությունը հեռացվում է, անհրաժեշտ չէ իրականացման ժամանակում տիպերի ստուգումներ կատարել, ինչը կարող է բարելավել կատարողականությունը:
Տիպերի վերացման թերությունները՝
- Անհնար է օգտագործել հիմնական տիպեր որպես ընդհանուր տիպերի պարամետրեր: Օրինակ,
ArrayList<int>չի թույլատրվում։ Դրա փոխարեն, օգտագործվում են նրանց օղակային տիպերը՝ArrayList<Integer>: - Տիպի մասին տեղեկատվության կորուստ իրականացման ժամանակ: Սա կարող է դժվարացնել որոշ գործողություններ, ինչպիսիք են ընդհանուր տիպի զանգվածի ստեղծումը (
new T[size]) կամ համապատասխանության ստուգումը (instanceof):
Օրինակ անորոշ վերածում՝
// Գումարային ցուցակի ստեղծում
List<String> stringList = new ArrayList<>();
stringList.add("Hello");
// Բայթկոդում դա տեսք ունի մոտավորապես՝
// List stringList = new ArrayList();
// stringList.add("Hello");
// Էլեմենտի ստացում ցուցակից
String greeting = stringList.get(0);
// Բայթկոդում, կոմպիլյատորը ավելացնում է cast՝
// String greeting = (String)stringList.get(0);
Սահմանափակված ընդհանուր տիպեր (Bounded wildcards) օգտագործվում են ավելի ճկուն տիպային կառավարման համար:
<? extends T>՝ նշանակում է ցանկացած տիպ, որը ընդլայնում է T-ը կամ հավասար է T-ին։ Թույլ է տալիս ընթերցել տարրերը որպես T կամ նրա ենթատեսակներ։<? super T>՝ նշանակում է ցանկացած տիպ, որը սահմանափակվում է T կամ նրա վերին տիպով։ Թույլ է տալիս ավելացնել T կամ նրա ենթատեսակների տարրեր։
// Օրինակ `<? extends>`-ի հետ
List<? extends Number> numbers = new ArrayList<Integer>();
Number num = numbers.get(0); // OK
// numbers.add(new Double(1.0)); // Կոմպիլյատորային սխալ
// Օրինակ `<? super>`-ի հետ
List<? super Integer> integers = new ArrayList<Number>();
integers.add(10); // OK
// Integer i = integers.get(0); // Կոմպիլյատորային սխալ, վերադառնում է Object