JavaRush /Блоги Java /Random-TG /Генерикҳо дар Java чистанд

Генерикҳо дар Java чистанд

Дар гурӯҳ нашр шудааст
Салом! Имрӯз мо дар бораи генерикҳо сӯҳбат хоҳем кард. Бояд бигӯям, ки шумо бисёр чизҳои навро меомӯзед! На танхо ин, балки якчанд лекцияхои оянда хам ба генерика бахшида мешаванд. Генерикҳо дар Java чистанд - 1 Аз ин рӯ, агар ин мавзӯъ барои шумо ҷолиб бошад, шумо хушбахт ҳастед: имрӯз шумо дар бораи хусусиятҳои генерикҳо бисёр чизҳоро меомӯзед. Хуб, агар не, ором шавед ва истироҳат кунед! :) Ин мавзӯи хеле муҳим аст ва шумо бояд онро донед. Биёед бо як содда оғоз кунем: "чӣ" ва "чаро". Генерикҳо чист? Генерикҳо намудҳое мебошанд, ки параметр доранд. Ҳангоми сохтани генерик, шумо на танҳо намуди он, балки навъи маълумотеро, ки бояд бо он кор кунад, муайян мекунед. Ман фикр мекунам, ки мисоли равшантарин аллакай ба сари шумо омадааст - ин ArrayList аст! Ин аст, ки чӣ тавр мо онро одатан дар барнома эҷод мекунем:
import java.util.ArrayList;
import java.util.List;

public class Main {

   public static void main(String[] args) {

       List<String> myList1 = new ArrayList<>();
       myList1.add("Test String 1");
       myList1.add("Test String 2");
   }
}
Тавре ки шумо тахмин карда метавонед, хусусияти рӯйхат дар он аст, ки ҳама чизро ба он "пур кардан" ғайриимкон аст: он танҳо бо an objectҳо кор мекунад String. Акнун биёед як экскурсияи кӯтоҳе ба таърихи Ява кунем ва кӯшиш кунем, ки ба саволи "чаро?" Барои ин мо худамон versionи соддакардашудаи синфи ArrayList-ро менависем. Рӯйхати мо танҳо метавонад ба массиви дохилӣ маълумот илова кунад ва ин маълумотро қабул кунад:
public class MyListClass {

   private Object[] data;
   private int count;

   public MyListClass() {
       this.data = new Object[10];
       this.count = 0;
   }

   public void add(Object o) {
       this.data[count] = o;
       count++;
   }

   public Object[] getData() {
       return data;
   }
}
Фарз мекунем, ки мо мехоҳем, ки рӯйхати мо танҳо рақамҳоро нигоҳ дорад Integer. Мо генерикҳо надорем. Мо наметавонем ба таври возеҳ мисоли чекро Integerдар add(). Он гоҳ тамоми синфи мо танҳо барои Integer. Мо тасмим гирифтем, ки ба барномасозони худ такя кунем ва танҳо дар code шарҳ гузорем, то онҳо дар он ҷо ягон чизи нолозимро илова накунанд:
//use it ONLY with Integer data type
public void add(Object o) {
   this.data[count] = o;
   count++;
}
Яке аз барномасозон ин шарҳро нодида гирифт ва нохост рақамҳои бо сатр омехташударо ба рӯйхат дохил карданӣ шуд ва сипас маблағи онҳоро ҳисоб кунад:
public class Main {

   public static void main(String[] args) {

       MyListClass list = new MyListClass();
       list.add(100);
       list.add(200);
       list.add("Lolkek");
       list.add("Shalala");

       Integer sum1 = (Integer) list.getData()[0] + (Integer) list.getData()[1];
       System.out.println(sum1);

       Integer sum2 = (Integer) list.getData()[2] + (Integer) list.getData()[3];
       System.out.println(sum2);
   }
}
Натиҷаи консол: 300 Истисно дар риштаи "main" java.lang.ClassCastException: java.lang.String наметавонад ба java.lang.Integer дар Main.main интиқол дода шавад(Main.java:14) Дар ин вазъият бадтарин кадом аст? Дур аз беэҳтиётӣ будани барномасоз. Бадтарин чиз он аст, ки рамзи нодуруст дар ҷои муҳими барномаи мо қарор гирифт ва бомуваффақият тартиб дода шуд . Акнун мо хатогиро на дар марҳилаи рамзгузорӣ, балки танҳо дар марҳилаи санҷиш мебинем (ва ин дар беҳтарин ҳолат аст!). Ислоҳи хатогиҳо дар марҳилаи таҳия хеле бештар арзиш дорад - ҳам пул ва ҳам вақт. Ин маҳз бартарии генерикҳост: синфи умумӣ ба барномасози бадбахт имкон медиҳад, ки хатогиро фавран ошкор кунад. Рамз танҳо тартиб дода намешавад!
import java.util.ArrayList;
import java.util.List;

public class Main {

   public static void main(String[] args) {

       List<Integer> myList1 = new ArrayList<>();

       myList1.add(100);
       myList1.add(100);
       myList1.add("Lolkek");//error!
       myList1.add("Shalala");//error!
   }
}
Барномасоз фавран «ба худ меояд» ва дарҳол худро ислоҳ мекунад. Воқеан, ба мо лозим набуд, ки синфи худамонро эҷод кунем List, то ин гуна хатогиҳоро бубинем. Танҳо қавсҳои навъи ( <Integer>) -ро аз ArrayList муқаррарӣ хориҷ кунед!
import java.util.ArrayList;
import java.util.List;

public class Main {

   public static void main(String[] args) {

      List list = new ArrayList();

      list.add(100);
      list.add(200);
      list.add("Lolkek");
      list.add("Shalala");

       System.out.println((Integer) list.get(0) + (Integer) list.get(1));
       System.out.println((Integer) list.get(2) + (Integer) list.get(3));
   }
}
Натиҷаи консол: 300 Истисно дар риштаи "main" java.lang.ClassCastException: java.lang.String наметавонад ба java.lang.Integer дар Main.main интиқол дода шавад(Main.java:16) Яъне, ҳатто бо истифода аз абзорҳои "модарӣ" Java, шумо метавонед ин хато кунед ва коллексияи хатарнок эҷод кунед. Аммо, агар мо ин codeро ба IDEa часбонем, мо огоҳиро мебинем: " Зангҳои тафтишнашуда барои илова кардан(E) ҳамчун узви навъи хоми java.util.List " Ин ба мо мегӯяд, ки ҳангоми илова кардани элемент ба файл метавонад чизе хато кунад. ҷамъоварӣ бе генерикҳо ин тавр нест. Аммо ибораи «навъи хом» чӣ маъно дорад? Тарҷумаи аслӣ хеле дақиқ хоҳад буд - " навъи хом " ё " навъи ифлос ". Raw typeсинфи умумӣ аст, ки навъи он аз он хориҷ карда шудааст. Ба ибораи дигар, List myList1ин аст Raw type. Баръакс як синфи умумӣ raw typeаст generic type(инчунин ҳамчун синф маълум аст parameterized type), ки дуруст ва бо мушаххасоти намуд сохта шудааст. Барои намуна, List<String> myList1. Шояд шумо саволе дошта бошед: чаро он ҳатто барои истифода иҷозат дода шудааст raw types? Сабаб оддӣ аст. Эҷодкорони Java дастгирӣро дар забон гузоштанд raw types, то мушкилоти мутобиқат эҷод накунанд. Вақте ки Java 5.0 бароварда шуд (генерикҳо бори аввал дар ин version пайдо шуданд), аллакай бисёр codeҳо бо истифода аз raw types. Аз ин рӯ, ин имкон имрӯз ҳам вуҷуд дорад. Мо дар лекцияхо китоби классикии Жошуа Блок «Яваи самарабахш»-ро на як бору ду бор зикр карда будем. У хамчун яке аз созандагони забон мавзуи истифода raw typesва дар китоб аз generic types. Генерикҳо дар Java чист - 2Боби 23-и ин китоб унвони хеле фасењ дорад: "Намудҳои хомро дар рамзи нав истифода набаред." Ин чизест, ки шумо бояд дар хотир доред. Ҳангоми истифодаи синфҳои умумӣ, ҳеҷ гоҳ онҳоро generic typeба raw type.

Усулҳои чопшуда

Java ба шумо имкон медиҳад, ки усулҳои инфиродӣ чоп карда, усулҳои ба истилоҳ умумӣ эҷод кунед. Чаро чунин усулҳо қулайанд? Пеш аз ҳама, зеро онҳо ба шумо имкон медиҳанд, ки бо намудҳои гуногуни параметрҳо кор кунед. Агар як мантиқро ба намудҳои гуногун бехатар истифода бурдан мумкин бошад, усули умумӣ як роҳи ҳалли олӣ аст. Биёед як мисолро дида бароем. Фарз мекунем, ки мо як рӯйхат дорем myList1. Мо мехоҳем, ки ҳамаи арзишҳоро аз он хориҷ кунем ва ҳама ҷойҳои холиро бо арзиши нав пур кунем. Синфи мо бо усули умумӣ чунин хоҳад буд:
public class TestClass {

   public static <T> void fill(List<T> list, T val) {
       for (int i = 0; i < list.size(); i++)
           list.set(i, val);
   }

   public static void main(String[] args) {

       List<String> strings = new ArrayList<>();
       strings.add("Старая строка 1");
       strings.add("Старая строка 2");
       strings.add("Старая строка 3");

       fill(strings, "Новая строка");

       System.out.println(strings);

       List<Integer> numbers = new ArrayList<>();
       numbers.add(1);
       numbers.add(2);
       numbers.add(3);

       fill(numbers, 888);
       System.out.println(numbers);
   }
}
Ба синтаксис диққат диҳед, он каме ғайриоддӣ менамояд:
public static <T> void fill(List<T> list, T val)
Дар пеши навъи бозгашт <T> гузошта шудааст, ки усули умумиро нишон медиҳад. Дар ин ҳолат, метод 2 параметрро ҳамчун вуруд қабул мекунад: рӯйхати an objectҳои T ва дигар an objectи алоҳидаи T. Бо истифода аз <T> чопкунии усул ба даст меояд: мо рӯйхати сатрҳо ва рақамро ба он ҷо интиқол дода наметавонем. Рӯйхати сатрҳо ва сатрҳо, рӯйхати рақамҳо ва рақамҳо, рӯйхати an objectҳои мо Catва an objectи дигар Cat- ин ягона роҳ аст. Ин усул main()ба таври возеҳ нишон медиҳад, ки усул fill()бо намудҳои гуногуни маълумот ба осонӣ кор мекунад. Аввалан, он ҳамчун вуруд рӯйхати сатрҳо ва сатр ва сипас рӯйхати рақамҳо ва рақамҳоро мегирад. Натиҷаи консол: [Newline, Newline, Newline] [888, 888, 888] Тасаввур кунед, ки оё fill()мо барои 30 синфҳои гуногун мантиқи метод лозим буд ва мо усулҳои умумӣ надорем. Мо маҷбур мешавем, ки як усулро 30 маротиба нависем, танҳо барои намудҳои гуногуни маълумот! Аммо ба шарофати усулҳои умумӣ, мо метавонем рамзи худро дубора истифода барем! :)

Синфҳои чопшуда

Шумо метавонед на танҳо дарсҳои умумиро, ки дар Java пешниҳод шудаанд, истифода баред, балки худатонро низ эҷод кунед! Инак як мисоли оддӣ:
public class Box<T> {

   private T t;

   public void set(T t) {
       this.t = t;
   }

   public T get() {
       return t;
   }

   public static void main(String[] args) {

       Box<String> stringBox = new Box<>();

       stringBox.set("Старая строка");
       System.out.println(stringBox.get());
       stringBox.set("Новая строка");

       System.out.println(stringBox.get());

       stringBox.set(12345);//ошибка компиляции!
   }
}
Синфи мо Box<T>(«қуттӣ») чоп карда мешавад. Ҳангоми таъин кардани навъи маълумот ( ) ба он <T>, мо дигар наметавонем an objectҳои намудҳои дигарро дар он ҷойгир кунем. Инро дар мисол дидан мумкин аст. Ҳангоми эҷод, мо муайян кардем, ки an objectи мо бо сатрҳо кор хоҳад кард:
Box<String> stringBox = new Box<>();
Ва вақте ки дар сатри охирини code мо кӯшиш мекунем, ки рақами 12345-ро дар дохor қуттӣ гузорем, мо хатои ҷамъоварӣ мегирем! Ба ҳамин монанд, мо синфи умумии худро таъсис додем! :) Бо ин лекцияи имрузаи мо ба охир мерасад. Аммо мо бо генерикҳо хайрбод намегӯем! Дар лексияҳои оянда мо дар бораи хусусиятҳои пешрафта сӯҳбат хоҳем кард, бинобар ин хайрбод нагӯед! ) Дар хонишатон барори кор! :)
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION