JavaRush /Java Blog /Random-TK /Pişikler üçin umumylyklar
Viacheslav
Dereje

Pişikler üçin umumylyklar

Toparda çap edildi
Pişikler üçin umumylyklar - 1

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);
  }
}
testOny 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.
Pişikler üçin umumylyklar - 2

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:
Pişikler üçin umumylyklar - 3
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);
  }
}
ListBu mysalda, diňe bir däl, diňe ListDiň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 :
Pişikler üçin umumylyklar - 4
Ş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 Listisleýä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.
Pişikler üçin umumylyklar - 5

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, Boxdiňe işleýän diňe özümiziň bardygyny görkezdik Cat. Düzüji, catBoxumumylygyň ýerine, geniň ady görkezilen ýerde Tgörnüşini çalyşmalydygyna düşündi : CatT
Pişikler üçin umumylyklar - 6
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: slotsList<Cat>Box<Dog>slotsList<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 Boxmirasdar däl Animalwe 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
Pişikler üçin umumylyklar - 7

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:

Pişikler üçin umumylyklar - 8
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ň:
Pişikler üçin umumylyklar - 9
Soň bolsa, şuňa meňzeş bir obýekt döredip bileris:
ArrayList<String> object = createObject(ArrayList.class);
Pişikler üçin umumylyklar - 10

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.
Pişikler üçin umumylyklar - 11

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 ”:
Pişikler üçin umumylyklar - 12
Aboveokarda aýdylyşy ýaly, bu mysalda umumy Tserhedi öçürildi. öň Comparable.
Pişikler üçin umumylyklar - 13

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
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION