Salam! Bu günki sapagymyzda generikany öwrenmegi dowam etdireris. Justöne şeýle bolýar, bu uly mowzuk, ýöne gidip boljak ýer ýok - bu diliň örän möhüm bölegi :) Oracle resminamalaryny generikler boýunça öwreneniňizde ýa-da internetde gollanmalary okasaňyz, şertlere duşarsyňyz. Düzedip bolmaýan görnüşler we gaýtadan dikeldilýän görnüşler . “Reifiable” haýsy söz? Iňlis dili bilen hemme zat gowy bolsa-da, onuň bilen duşuşmagyňyz gaty ähtimal. Terjime etmäge synanyşalyň!
* Google-a sag bol, köp kömek etdiň -_- *
Gaýtadan ulanylýan görnüş, iş wagty doly elýeterli bolan görnüşdir. Java dilinde bulara primitiwler, çig görnüşler we umumy däl görnüşler girýär. Munuň tersine, yzyna gaýtaryp bolmaýan görnüşler , maglumatlary pozulýan we iş wagty elýeterli bolmadyk görnüşlerdir. Bular diňe umumylyklar - Sanaw <String> , Sanaw <Integer> we ş.m.
Theeri gelende aýtsak, vararglaryň nämedigini ýadyňyzdamy ?
Forgatdan çykaran bolsaňyz, üýtgeýän uzynlyk argumentleri. Usulymyza näçe argumentiň geçirilip bilinjekdigini bilmeýän ýagdaýlarymyzda amatly bolýar. Mysal üçin, kalkulýator synpymyz bar bolsa we onuň usuly barsum
. 2, 3, 5 ýa-da usuly sum()
näçe isleseňiz geçirip bilersiňiz . sum()
Mümkin bolan ähli wariantlary göz öňünde tutmak üçin usuly her gezek artykmaç ýüklemek gaty geň zat . Munuň ýerine muny edip bileris:
public class SimpleCalculator {
public static int sum(int...numbers) {
int result = 0;
for(int i : numbers) {
result += i;
}
return result;
}
public static void main(String[] args) {
System.out.println(sum(1,2,3,4,5));
System.out.println(sum(2,9));
}
}
Konsol çykyşy:
15
11
Şeýlelik bilen, generika bilen bilelikde ulanylanda varargs
käbir möhüm aýratynlyklar bar. Geliň şu koda seredeliň:
import javafx.util.Pair;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static <E> void addAll(List<E> list, E... array) {
for (E element : array) {
list.add(element);
}
}
public static void main(String[] args) {
addAll(new ArrayList<String>(), // здесь все нормально
"Leonardo da Vinci",
"Vasco de Gama"
);
// а здесь мы получаем предупреждение
addAll(new ArrayList<Pair<String, String>>(),
new Pair<String, String>("Leonardo", "da Vinci"),
new Pair<String, String>("Vasco", "de Gama")
);
}
}
Usul sanawy we islendik sanly obýekti addAll()
giriş hökmünde alýar we soňra bu obýektleriň hemmesini sanawa goşýar. Usulda usulymyza iki gezek diýýäris . Ilkinji gezek iki yzygiderli setir goşýarys . Bu ýerde hemme zat gowy. Ikinji gezek iki obýekt goşýarys . Ine, birden duýduryş alýarys: List<E>
E
main()
addAll()
List
List
Pair<String, String>
Unchecked generics array creation for varargs parameter
Bu näme many berýär? Näme üçin duýduryş alýarys we munuň bilen näme baglanyşygy bar array
? Array
- bu bir massiw, kodumyzda hiç hili massiw ýok! Ikinjisinden başlalyň. Duýduryşda bir massiw agzalýar, sebäbi düzüji üýtgeýän uzynlyk argumentlerini (varargs) massiwine öwürýär. Başgaça aýdylanda, usulymyzyň goly addAll()
:
public static <E> void addAll(List<E> list, E... array)
Aslynda şeýle görünýär:
public static <E> void addAll(List<E> list, E[] array)
Methodagny, usulda main()
düzüji kodumyzy şoňa öwürer:
public static void main(String[] args) {
addAll(new ArrayList<String>(),
new String[] {
"Leonardo da Vinci",
"Vasco de Gama"
}
);
addAll(new ArrayList<Pair<String,String>>(),
new Pair<String,String>[] {
new Pair<String,String>("Leonardo","da Vinci"),
new Pair<String,String>("Vasco","de Gama")
}
);
}
Hemme zat massiw bilen gowy String
. Aöne bir massiw bilen Pair<String, String>
- ýok. Hakykat, Pair<String, String>
bu yzyna gaýtaryp bolmajak görnüş. Ilygyndy wagtynda parametr görnüşleri (<Setir, setir>) baradaky ähli maglumatlar öçüriler. Java-da gaýtadan dikeldilmeýän görnüşden massiw döretmek gadagan . Jübüt <Setir, setir> massiwini el bilen döretjek bolsaňyz, muny tassyklap bilersiňiz
public static void main(String[] args) {
// ошибка компиляции! Generic array creation
Pair<String, String>[] array = new Pair<String, String>[10];
}
Sebäbi görnüp dur - howpsuzlygy ýazyň. Aadyňyzda bolsa, bir massiw döredilende, bu massiwiň haýsy obýektleriň (ýa-da başlangyç) saklanjakdygyny görkezmeli.
int array[] = new int[10];
Öňki sapaklaryň birinde görnüşini pozmagyň mehanizmini jikme-jik gözden geçirdik. Şeýlelik bilen, bu ýagdaýda görnüşleriň pozulmagy netijesinde Pair
jübütleriň obýektlerimizde saklanýandygy baradaky maglumatlary ýitirdik <String, String>
. Bir massiw döretmek howply bolmaz. Usullar we umumylyklar ulanylanda varargs
, görnüşi pozmagy we onuň nähili işleýändigini ýadyňyzdan çykarmaň. Wroteazan koduňyza doly ynanýan bolsaňyz we hiç hili kynçylyk döretmejekdigini bilýän bolsaňyz, varargs
düşündiriş bilen baglanyşykly duýduryşlary öçürip bilersiňiz.@SafeVarargs
@SafeVarargs
public static <E> void addAll(List<E> list, E... array) {
for (E element : array) {
list.add(element);
}
}
Bu düşündirişi usulyňyza goşsaňyz, öň gören duýduryşymyz peýda bolmaz. Generikleri bilelikde ulananyňyzda başga bir mesele, varargs
üýşmek hapalanmagydyr. Hapalanma aşakdaky ýagdaýlarda ýüze çykyp biler:
import java.util.ArrayList;
import java.util.List;
public class Main {
static List<String> makeHeapPollution() {
List numbers = new ArrayList<Number>();
numbers.add(1);
List<String> strings = numbers;
strings.add("");
return strings;
}
public static void main(String[] args) {
List<String> stringsWithHeapPollution = makeHeapPollution();
System.out.println(stringsWithHeapPollution.get(0));
}
}
Konsol çykyşy:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
Simpleönekeý söz bilen aýdylanda, üýşmek hapalanmagy 1-nji görnüşli obýektleriň üýşmeleňde bolmaly ýagdaýy , ýöne görnüşdäki howpsuzlyk ýalňyşlyklary sebäpli А
görnüşdäki zatlar şol ýerde gutarýar . B
Mysalymyzda şeýle bolýar. Ilki bilen çig üýtgeýjini döretdik numbers
we umumy kolleksiýa belledik ArrayList<Number>
. Şondan soň belgini şol ýere goşduk 1
.
List<String> strings = numbers;
Bu setirde, düzüji bize " Barlanmadyk tabşyryk ... " duýduryşyny bermek bilen bolup biljek ýalňyşlyklar barada duýduryş bermäge synanyşdy, ýöne biz muňa ähmiýet bermedik. Netijede, List<String>
görnüşiň umumy ýygyndysyny görkezýän görnüşiň umumy üýtgeýjisi bar ArrayList<Number>
. Bu ýagdaý aç-açan kynçylyklara sebäp bolup biler! Bu şeýle bolýar. Täze üýtgeýjimizi ulanyp, kolleksiýa setir goşýarys. Toprak hapalandy - ilki san, soň ýazylan kolleksiýa setir goşduk. Düzediji bize duýduryş berdi, ýöne ClassCastException
diňe programma işleýän wagtynda netijeleri alyp, onuň duýduryşyna ähmiýet bermedik. Munuň bilen näme baglanyşygy bar varargs
? Generika bilen ulanmak varargs
aňsatlyk bilen üýşmegiň hapalanmagyna sebäp bolup biler. Ine ýönekeý mysal:
import java.util.Arrays;
import java.util.List;
public class Main {
static void makeHeapPollution(List<String>... stringsLists) {
Object[] array = stringsLists;
List<Integer> numbersList = Arrays.asList(66,22,44,12);
array[0] = numbersList;
String str = stringsLists[0].get(0);
}
public static void main(String[] args) {
List<String> cars1 = Arrays.asList("Ford", "Fiat", "Kia");
List<String> cars2 = Arrays.asList("Ferrari", "Bugatti", "Zaporozhets");
makeHeapPollution(cars1, cars2);
}
}
Bu ýerde näme bolýar? Görnüşiň pozulmagy sebäpli, parametrlerimiz (amatlylyk üçin “sanawlaryň” ýerine “listler” diýeris) -
List<String>...stringsLists
- List[]
näbelli görnüş bilen (köp sanly ýygyndy görnüşinde yzygiderli massiwlere öwrülýändigini ýatdan çykarmaň). Şol sebäpli usulyň birinji setirinde üýtgeýjä aňsatlyk bilen tabşyryp bileris Object[] array
- görnüşler sahypalarymyzdan öçürildi! Indi bolsa üýtgeýän bir görnüşimiz bar Object[]
, bu ýerde asla islendik zat goşup bileris - Java-daky ähli obýektler miras alýar Object
! Häzirki wagtda diňe bir topar setir sahypalary bar. Typesöne görnüşleriň ulanylmagy we pozulmagy netijesinde varargs
, olara aňsatlyk bilen sanlar sahypasyny goşup bileris. Netijede, dürli görnüşli zatlary garyşdyryp, üýşmegi hapalaýarys. ClassCastException
Toplumdan bir setir okamaga synanyşanyňyzda netije şol bir kadadan çykma bolar . Konsol çykyşy:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
Simpleönekeý ýaly görünýän mehanizmi ulanmagyň netijesinde bolup biläýjek garaşylmadyk netijeler varargs
:) Ine, şu günki leksiýamyz gutarýar. Birnäçe meseläni çözmegi ýatdan çykarmaň, wagtyňyz we güýjüňiz galan bolsa, goşmaça edebiýaty öwreniň. “ Netijeli Java ” özüni okamaz! :) Görüşýänçäk!
GO TO FULL VERSION