Giriş
Bu gün Java hakda bilýänlerimizi ýada salmak üçin ajaýyp gün. Iň möhüm resminama laýyklykda, ýagny
Java dil spesifikasiýasy (JLS - Java dil spesifikasiýasy), Java "4-nji bap" görnüşleri, bahalary we üýtgeýänleri " bölüminde beýan edilişi ýaly güýçli ýazylan dil . Bu näme many berýär? Esasy usulymyz bar diýeliň:
public static void main(String[] args) {
String text = "Hello world!";
System.out.println(text);
}
Güýçli ýazmak, bu kod düzülende düzüji, tekst üýtgeýjisiniň görnüşini String diýip kesgitlän bolsak, ony başga bir görnüşiň üýtgeýjisi hökmünde ulanmaga synanyşmaýarys (mysal üçin, Integer) . Mysal üçin, tekstiň ýerine bir bahany tygşytlamaga synanyşsak
2L
(meselem, Stringiň ýerine uzyn), düzülen wagty ýalňyşlyk alarys:
Main.java:3: error: incompatible types: long cannot be converted to String
String text = 2L;
Bular. Güýçli ýazmak, obýektlerdäki amallaryň diňe şol amallar şol obýektler üçin kanuny bolan ýagdaýynda ýerine ýetirilmegini üpjün etmäge mümkinçilik berýär. Muňa görnüşiň howpsuzlygy hem diýilýär. JLS-de aýdylyşy ýaly, Java-da iki görnüş bar: başlangyç görnüşler we salgylanma görnüşleri. Syn makalasyndan ýönekeý görnüşler barada ýadyňyzda saklap bilersiňiz: “
Java-da başlangyç görnüşler: Olar beýle bir ýönekeý däl .” Salgy görnüşleri synp, interfeýs ýa-da massiw bilen görkezilip bilner. Bu gün bolsa salgylanma görnüşleri bilen gyzyklanarys. Geliň, massiwlerden başlalyň:
class Main {
public static void main(String[] args) {
String[] text = new String[5];
text[0] = "Hello";
}
}
Bu kod ýalňyşsyz işleýär. Bilşimiz ýaly (mysal üçin, "
Oracle Java Tutorial: Arrays " -dan), bir massiw diňe bir görnüşdäki maglumatlary saklaýan gapdyr. Bu ýagdaýda - diňe setirler. Setiriň ýerine massiwde uzyn goşmaga synanyşalyň:
text[1] = 4L;
Geliň, bu kody işledeliň (mysal üçin,
Repl.it Online Java Compiler- de ) we ýalňyşlyk alalyň:
error: incompatible types: long cannot be converted to String
Diliň görnüşi we görnüşiniň howpsuzlygy, görnüşine laýyk gelmeýän bir massiwde saklamaga mümkinçilik bermedi. Bu görnüş howpsuzlygynyň ýüze çykmasydyr. Bize: "erroralňyşlygy düzediň, ýöne şoňa çenli kod düzüp bilmerin" diýdiler. Iň möhüm zat, bu programma işe girizilende däl-de, düzülende bolýar. .Agny, ýalňyşlyklary derrew görýäris, “bir gün” däl. Toplumlar hakda ýadymyzdan çykansoň, geliň
Java kolleksiýalary çarçuwasy barada hem ýatda saklalyň . Ol ýerde dürli gurluşlarymyz bardy. Mysal üçin, sanawlar. Mysaly täzeden ýazalyň:
import java.util.*;
class Main {
public static void main(String[] args) {
List text = new ArrayList(5);
text.add("Hello");
text.add(4L);
String test = text.get(0);
}
}
test
Ony düzenimizde üýtgeýän başlangyç setirinde ýalňyşlyk alarys :
incompatible types: Object cannot be converted to String
Biziň ýagdaýymyzda, sanaw islendik obýekti saklap biler (meselem, obýekt görnüşindäki obýekt). Şonuň üçin düzüjiniň beýle jogapkärçilik ýüküni alyp bilmejekdigini aýdýar. Şonuň üçin sanawdan aljak görnüşimizi aç-açan kesgitlemeli:
String test = (String) text.get(0);
Bu görkezişe görnüş öwrülişi ýa-da görnüşli guýma diýilýär. Elementi 1 indeksde almaga synanyşýançak hemme zat gowy bolar, sebäbi Uzyn görnüşli. Adalatly ýalňyşlyk alarys, ýöne programma işleýän wagtynda (Iş wagty):
type conversion, typecasting
Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String
Görşümiz ýaly, bu ýerde birnäçe möhüm kemçilikler bar. Ilki bilen, sanawdan alnan bahany String synpyna “zyňmaga” mejbur bolýarys. Razy, bu erbet. Ikinjiden, ýalňyşlyk ýüze çykan halatynda ony diňe programma ýerine ýetirilende göreris. Kodumyz has çylşyrymly bolsa, derrew beýle ýalňyşlygy ýüze çykaryp bilmezdik. Döredijiler şeýle ýagdaýlarda işi nädip aňsatlaşdyrmalydygy we kod has düşnükli boljakdygy hakda pikirlenip başladylar. Olar dünýä indi.
Generika
Şeýlelik bilen, generika. Bu näme? Umumy, kod düzüjiniň görnüşiň howpsuzlygyny üpjün etmek üçin ulanyp biljek görnüşlerini suratlandyrmagyň aýratyn usulydyr. Bu bir zat ýaly:
Ine gysga mysal we düşündiriş:
import java.util.*;
class Main {
public static void main(String[] args) {
List<String> text = new ArrayList<String>(5);
text.add("Hello");
text.add(4L);
String test = text.get(1);
}
}
List
Bu mysalda, diňe bir däl, diňe
List
Diňe String görnüşli obýektler bilen işleýän diýýäris . Beýlekiler ýok. Justaňy ýaýyň içinde görkezilen zatlar, ony saklap bileris. Şeýle "ýaýlara" "burç ýaýlar" diýilýär, ýagny burç ýaýlary Düzüji setirleriň sanawy bilen işlänimizde haýsydyr bir ýalňyşlyk goýberendigimizi ýa-da ýokdugymyzy barlar (sanawyň ady tekstdir). Düzüji, Uzynlygy setir sanawyna girizmäge synanyşýandygymyzy görer. Compygyndy wagtynda bolsa ýalňyşlyk berer:
error: no suitable method found for add(long)
Stringiň CharSequence-iň neslidigini ýadyňyzda bolsa gerek. We şuňa meňzeş bir zady etmek kararyna geliň:
public static void main(String[] args) {
ArrayList<CharSequence> text = new ArrayList<String>(5);
text.add("Hello");
String test = text.get(0);
}
Emma bu mümkin däl we ýalňyşlygy alarys:
error: incompatible types: ArrayList<String> cannot be converted to ArrayList<CharSequence>
Geň görünýär, sebäbi. setirde
CharSequence sec = "test";
hiç hili ýalňyşlyk ýok. Geliň muny anyklalyň. Bu gylyk-häsiýet hakda: "Generika üýtgemeýär". "Üýtgeşik" näme?
Wikipediýada " Covariance and contravariance " makalasynda bu barada nähili aýdylýandygyny haladym :
Şeýlelik bilen, “Invariance” alnan görnüşleriň arasynda mirasyň ýoklugydyr. Pişik Haýwanlaryň bir görnüşi bolsa, <Cats> toplumy <Haýwanlar> toplumynyň görnüşi däl we <Haýwanlar> toplumy <Pişikler> toplumynyň görnüşi däl. Theeri gelende aýtsak, Java SE 7-den başlap, “Almaz
operatory ” diýlip atlandyryldy. Sebäbi iki burçly ýaýlar <> göwher ýalydyr. Bu bize şuňa meňzeş generikleri ulanmaga mümkinçilik berýär:
public static void main(String[] args) {
List<String> lines = new ArrayList<>();
lines.add("Hello world!");
System.out.println(lines);
}
Bu koda esaslanyp, düzüji çep tarapda String görnüşli obýektleriň bardygyny görkezsek , sag tarapda täze ArrayList-i üýtgeýjä ýazdyrmak
List
isleýändigimize düşünýär , bu hem bir obýekti hem saklar.
lines
çep tarapynda görkezilen görnüşiň. Şeýlelik bilen çep tarapdan düzüji sag tarapyň görnüşine düşünýär ýa-da bozýar. Şonuň üçin bu gylyk-häsiýet iňlis dilinde “Type inference” ýa-da “Type Inference” diýilýär. Bellemeli ýene bir gyzykly zat, RAW görnüşleri ýa-da “çig görnüşler”. Sebäbi Generikler elmydama töwereginde däldi we Java mümkin boldugyça yza gabat gelýänligi saklamaga synanyşýar, soň generikler haýsydyr bir umumy görkezilmedik kod bilen işlemäge mejbur bolýarlar. Mysal göreliň:
List<CharSequence> lines = new ArrayList<String>();
.Adymyzda bolsa, generikleriň üýtgemezligi sebäpli beýle setir düzülmez.
List<Object> lines = new ArrayList<String>();
Şol bir sebäbe görä, bu hem düzülmez.
List lines = new ArrayList<String>();
List<String> lines2 = new ArrayList();
Şeýle setirler jemlener we işlär. Olarda çig görnüşler ulanylýar, ýagny kesgitlenmedik görnüşleri. Çig görnüşleriň häzirki zaman kodunda ulanylmaly däldigini ýene bir gezek bellemelidiris.
Görkezilen synplar
Şeýlelik bilen, ýazylan synplar. Öz ýazan synpymyzy nädip ýazyp biljekdigimizi göreliň. Mysal üçin, bizde synp iýerarhiýasy bar:
public static abstract class Animal {
public abstract void voice();
}
public static class Cat extends Animal {
public void voice(){
System.out.println("Meow meow");
}
}
public static class Dog extends Animal {
public void voice(){
System.out.println("Woof woof");
}
}
Haýwan gap-gaçlaryny ýerine ýetirýän synp döretmek isleýäris. Islän synpy ýazyp bolardy
Animal
. Bu ýönekeý, düşnükli, UTöne ... itleri we pişikleri garyşdyrmak erbet, biri-biri bilen dost däl. Mundan başga-da, kimdir biri şeýle konteýner alsa, ýalňyşlyk bilen gapdan pişikleri itler paketine taşlap biler ... we bu hiç hili peýdasyna getirmez. Ine, generika bize kömek eder. Mysal üçin, ýerine ýetirişini şeýle ýazalyň:
public static class Box<T> {
List<T> slots = new ArrayList<>();
public List<T> getSlots() {
return slots;
}
}
Biziň synpymyz T. atly umumy tarapyndan görkezilen görnüşli zatlar bilen işlär. Bu bir lakam. Sebäbi Umumy synpyň adynda görkezilýär, soň synp yglan edilende alarys:
public static void main(String[] args) {
Box<Cat> catBox = new Box<>();
Cat murzik = new Cat();
catBox.getSlots().add(murzik);
}
Görşümiz ýaly,
Box
diňe işleýän diňe özümiziň bardygyny görkezdik
Cat
. Düzüji,
catBox
umumylygyň ýerine, geniň ady görkezilen ýerde
T
görnüşini çalyşmalydygyna düşündi :
Cat
T
Bular. düzüjiniň aslynda nämäniň bolmalydygyna
Box<Cat>
düşünýändigi üçin minnetdar . Içinde , içinde bolar . Görnüş deklarasiýasynda birnäçe generika bolup biler, mysal üçin:
slots
List<Cat>
Box<Dog>
slots
List<Dog>
public static class Box<T, V> {
Umumy ady islendik zat bolup biler, ýöne aýdylmadyk käbir düzgünlere - "Görnüş parametrleriniň atlandyryş konwensiýalaryna" boýun bolmak maslahat berilýär: Elementiň görnüşi - E, açar görnüşi - K, san görnüşi - N, T - görnüşi, V - baha görnüşi üçin . Theeri gelende aýtsak, generikleriň üýtgewsizdigini aýtdyk. miras iýerarhiýasyny saklamaň. Aslynda, muňa täsir edip bileris. Genagny, generikleri COvariant, ýagny ýasamaga mümkinçiligimiz bar. miraslary şol bir tertipde saklamak. Bu özüni alyp barşyna "Çäklendirilen görnüş" diýilýär, ýagny çäkli görnüşleri. Mysal üçin, synpymyzda
Box
ähli haýwanlar bolup bilerdi, şonda şuňa meňzeş umumy yglan ederdik:
public static class Box<T extends Animal> {
.Agny, synpyň iň ýokary çägini belledik
Animal
. Şeýle hem açar sözden soň birnäçe görnüşi kesgitläp bileris
extends
. Bu, biziň işlejek görnüşimiziň käbir synpyň neslinden bolmalydygyny we şol bir wagtyň özünde käbir interfeýsi durmuşa geçirmelidigini aňladýar. Mysal üçin:
public static class Box<T extends Animal & Comparable> {
Bu ýagdaýda
Box
mirasdar däl
Animal
we durmuşa geçirmeýän bir zady goýjak bolsak
Comparable
, düzmek wagtynda ýalňyşlyk alarys:
error: type argument Cat is not within bounds of type-variable T
Usul ýazmak
Generika diňe bir görnüşlerde däl, eýsem aýratyn usullarda hem ulanylýar. Usullaryň ulanylyşyny resmi sapakda görmek bolýar: "
Umumy usullar ".
Maglumat:
Geliň, şu surata seredeliň. Görşüňiz ýaly, düzüji usulyň goluna seredýär we giriş hökmünde kesgitlenmedik synpy alýandygymyzy görýär. Gol bilen haýsydyr bir obýekti yzyna gaýtaryp berýändigimizi kesgitlemeýär. Obýekt. Şonuň üçin “ArrayList” döretmek islesek, muny etmeli:
ArrayList<String> object = (ArrayList<String>) createObject(ArrayList.class);
Çykyşyň “ArrayList” boljakdygyny aç-açan ýazmaly, bu erbet we ýalňyşlyk goýbermek mümkinçiligini goşýar. Mysal üçin, şeýle bolgusyz zatlary ýazyp bileris we düzer:
ArrayList object = (ArrayList) createObject(LinkedList.class);
Kompilýora kömek edip bilerismi? Hawa, generikler muny etmäge mümkinçilik berýär. Geliň, şol bir mysala seredeliň:
Soň bolsa, şuňa meňzeş bir obýekt döredip bileris:
ArrayList<String> object = createObject(ArrayList.class);
WildCard
Oracle-yň Generika boýunça okuw gollanmasyna, esasanam "
Wildcards " bölümine görä, sorag belgisi bilen "näbelli görnüşi" suratlandyryp bileris. “Wildcard”, umumy önümleriň käbir çäklendirmelerini azaltmak üçin amatly guraldyr. Mysal üçin, ozal belläp geçişimiz ýaly, generikler üýtgemeýär. Diýmek, ähli synplar Obýekt görnüşiniň nesilleri (kiçi görnüşleri) bolsa-da, onuň
List<любой тип>
kiçi görnüşi däl
List<Object>
. UTöne
List<любой тип>
bu bir kiçi görnüş
List<?>
. Şonuň üçin aşakdaky kody ýazyp bileris:
public static void printList(List<?> list) {
for (Object elem: list) {
System.out.print(elem + " ");
}
System.out.println();
}
Adaty generikler ýaly (ýagny, kartoçkalary ulanmazdan), kartoçkaly generikler çäklendirilip bilner. Upperokarky çäkli ýabany kartoçka tanyş ýaly görünýär:
public static void printCatList(List<? extends Cat> list) {
for (Cat cat: list) {
System.out.print(cat + " ");
}
System.out.println();
}
Alsoöne aşaky baglanyşyk kartoçkasy bilen çäklendirip bilersiňiz:
public static void printCatList(List<? super Cat> list) {
Şeýlelik bilen, usul iýerarhiýada has ýokary (Obýekte çenli) ähli pişikleri kabul edip başlar.
Erasure ýazyň
Generika barada aýdanymyzda, “Type Erasing” hakda bilmeli. Aslynda, görnüşi pozmak, generikleriň düzüji üçin maglumatdygy bilen baglanyşykly. Programmanyň ýerine ýetirilişinde generikler barada başga maglumat ýok, bu "pozmak" diýilýär. Bu pozmak, umumy görnüşiň belli bir görnüş bilen çalşylmagyna täsir edýär. Generalyň serhedi ýok bolsa, Obýektiň görnüşi çalşyrylar. Serhet görkezilen bolsa (mysal üçin
<T extends Comparable>
), onda onuň ornuny tutar. Ine, “Oracle” -yň gollanmasyndan bir mysal: “
Umumy görnüşleriň pozulmagy ”:
Aboveokarda aýdylyşy ýaly, bu mysalda umumy
T
serhedi öçürildi. öň
Comparable
.
Netije
Generika gaty gyzykly mowzuk. Bu mowzuk sizi gyzyklandyrar diýip umyt edýärin. Jemläp aýtsak, generikleriň bir tarapdan görnüşiň howpsuzlygyny we beýleki tarapdan çeýeligini üpjün etmek üçin düzüjini goşmaça maglumatlar bilen üpjün etmek üçin döredijileriň alan ajaýyp guralydygyny aýdyp bileris. Eger gyzyklanýan bolsaňyz, göwnüme ýaraýan çeşmeleri barlamagy maslahat berýärin:
# Wiaçeslaw
GO TO FULL VERSION