JavaRush /Блоги Java /Random-TG /Истифодаи varargs ҳангоми кор бо генерикҳо

Истифодаи varargs ҳангоми кор бо генерикҳо

Дар гурӯҳ нашр шудааст
Салом! Дар дарси имрӯза мо омӯзиши генералиро идома медиҳем. Ҳамин тавр мешавад, ки ин як мавзӯи калон аст, аммо ҷои рафтан нест - ин як қисми хеле муҳими забон аст :) Вақте ки шумо ҳуҷҷатҳои Oracle-ро оид ба генерикҳо меомӯзед ё дастурҳоро дар Интернет мехонед, шумо бо истилоҳот дучор мешавед. Намудҳои барқарорнашаванда ва намудҳои барқароршаванда . Чӣ гуна калимаи "Reifiable" аст? Ҳатто агар бо забони англисӣ ҳама чиз хуб бошад ҳам, шумо гумон аст, ки бо он вохӯред. Биёед кӯшиш кунем, ки тарҷума кунем! Истифодаи varargs ҳангоми кор бо генерикҳо - 2
* ташаккур ба Google, шумо бисёр кӯмак кардед -_-*
Навъи такроршаванда як намудест, ки иттилооти он дар вақти корӣ пурра дастрас аст. Дар забони Java инҳо ибтидоӣ, навъҳои хом ва навъҳои ғайриумумиро дар бар мегиранд. Баръакси ин, Намудҳои Таҷдиднашаванда навъҳое мебошанд, ки маълумоташон дар вақти корӣ нест карда мешавад ва дастнорас мегардад. Инҳо танҳо умумӣ мебошанд - List<String> , List<Integer> ва ғайра.

Дар омади гап, шумо дар хотир доред, ки вараргҳо чист ?

Агар шумо фаромӯш карда бошед, ин далелҳои дарозии тағйирёбанда мебошанд. Онҳо дар ҳолатҳое муфиданд, ки мо намедонем, ки чанд далелро ба усули мо интиқол додан мумкин аст. Масалан, агар мо синфи ҳисобкунак дошта бошем ва он дорои усули sum. sum()Шумо метавонед 2 рақам, 3, 5 ё ҳар қадаре, ки мехоҳед, ба усул гузаред. sum()Барои ба инобат гирифтани ҳамаи имконоти имконпазир ҳар дафъа усули изофабор кардан хеле аҷиб мебуд . Ба ҷои ин мо метавонем ин корро кунем:
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));
   }
}
Натиҷаи консол:

15
11
Ҳамин тавр, истифода varargsдар якҷоягӣ бо генерикҳо дорои баъзе хусусиятҳои муҳим аст. Биёед ин codeро бубинем:
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")
       );
   }
}
Ин усул рӯйхат ва ҳама гуна шумораи an objectҳоро addAll()ҳамчун вуруд мегирад ва сипас ҳамаи ин an objectҳоро ба рӯйхат илова мекунад. Дар усул мо усули худро ду маротиба даъват мекунем . Бори аввал мо дар ду хати муқаррарӣ илова мекунем. Дар ин ҷо ҳама чиз хуб аст. Дафъаи дуюм мо ба ду an object илова мекунем . Ва дар ин ҷо мо ногаҳон огоҳӣ мегирем: List<E>Emain()addAll()ListListPair<String, String>

Unchecked generics array creation for varargs parameter
Ин чӣ маъно дорад? Чаро мо огоҳӣ мегирем ва он ба он чӣ иртибот дорад array? Array- ин массив аст ва дар codeи мо ягон массив вуҷуд надорад! Биёед бо дуюм оғоз кунем. Огоҳӣ массивро зикр мекунад, зеро компилятор аргументҳои дарозии тағирёбандаро (varargs) ба массив табдил медиҳад. Ба ибораи дигар, имзои усули мо ин аст addAll():
public static <E> void addAll(List<E> list, E... array)
Он воқеан чунин менамояд:
public static <E> void addAll(List<E> list, E[] array)
Яъне, дар усули main(), компилятор рамзи моро ба ин табдил медиҳад:
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")
        }
   );
}
Ҳама чиз бо массив хуб аст String. Аммо бо массив Pair<String, String>- не. Далели он аст, ки Pair<String, String>ин як намуди ғайриимкон аст. Ҳангоми тартибдиҳӣ ҳама маълумот дар бораи намудҳои параметрҳо (<Стринг, Сатр>) тоза карда мешаванд. Дар Java эҷод кардани массивҳо аз навъи Non-Reifiable иҷозат дода намешавад . Шумо метавонед инро тафтиш кунед, агар шумо кӯшиш кунед, ки массивро дастӣ эҷод кунед Pair<String, String>
public static void main(String[] args) {

   //  ошибка компиляции! Generic array creation
  Pair<String, String>[] array = new Pair<String, String>[10];
}
Сабаб равшан аст - намуди бехатарӣ. Тавре ки шумо дар хотир доред, ҳангоми сохтани массив, шумо бояд нишон диҳед, ки ин массив кадом an objectҳоро (ё примитивҳоро) нигоҳ медорад.
int array[] = new int[10];
Дар яке аз дарсҳои қаблӣ мо механизми тозакунии типро ба таври муфассал баррасӣ кардем. Ҳамин тавр, дар ин ҳолат, дар натиҷаи тоза кардани намудҳо, мо маълумотеро гум кардем, ки Pairҷуфтҳо дар an objectҳои мо нигоҳ дошта мешаванд <String, String>. Эҷоди массив хатарнок хоҳад буд. Ҳангоми истифодаи усулҳо бо varargsва генерикҳо, ҳатман дар бораи тозакунии навъи ва маҳз чӣ гуна кор кардани он дар хотир доред. Агар шумо комилан ба рамзи навиштаатон боварӣ дошта бошед ва медонед, ки он ҳеҷ гуна мушкилоте ба бор намеорад, шумо метавонед varargsогоҳиҳои марбут ба онро бо истифода аз эзоҳ хомӯш кунед@SafeVarargs
@SafeVarargs
public static <E> void addAll(List<E> list, E... array) {

   for (E element : array) {
       list.add(element);
   }
}
Агар шумо ин эзоҳро ба усули худ илова кунед, огоҳие, ки мо қаблан дучор шуда будем, пайдо намешавад. Мушкилоти дигари имконпазир ҳангоми истифодаи varargsякҷояи генерикҳо ифлосшавии теппа мебошад. Истифодаи varargs ҳангоми кор бо генерикҳо - 4Инфрасохтор метавонад дар ҳолатҳои зерин рух диҳад:
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));
   }
}
Натиҷаи консол:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
Ба ибораи оддӣ, ифлосшавии тӯда вазъиятест, ки дар он an objectҳои навъи 1 бояд дар теппа бошанд А, аммо an objectҳои навъи он Bбо сабаби хатогиҳои бехатарии навъи он ба анҷом мерасанд. Дар мисоли мо чунин аст. Аввал мо як тағирёбандаи Raw эҷод кардем numbersва ба он коллексияи умумӣ таъин кардем ArrayList<Number>. Пас аз он мо рақамро дар он ҷо илова кардем 1.
List<String> strings = numbers;
Дар ин сатр, компилятор кӯшиш кард, ки моро дар бораи хатогиҳои эҳтимолӣ бо додани огоҳии " Супориши тафтишнашуда ... " огоҳ кунад, аммо мо онро нодида гирифтем. Дар натиҷа, мо як тағирёбандаи умумии type дорем List<String>, ки ба маҷмӯи умумии type ишора мекунад ArrayList<Number>. Ин вазъият ба таври равшан метавонад боиси мушкилот гардад! Ин аст он чизе ки рӯй медиҳад. Бо истифода аз тағирёбандаи нави худ, мо ба коллексия сатр илова мекунем. Тӯда ифлос шуд - мо ба коллексияи чопшуда аввал рақам ва баъд сатр илова кардем. Компилятор моро огоҳ кард, аммо мо ба огоҳии он аҳамият надодем ва натиҷаҳоро ClassCastExceptionтанҳо ҳангоми иҷрои барнома ба даст овардем. Ба он чи дахл дорад varargs? Истифодаи varargsгенерикҳо метавонад ба осонӣ ба ифлосшавии тӯда оварда расонад. Инак як мисоли оддӣ:
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);
   }
}
Дар ин ҷо чӣ гап? Аз сабаби тозакунии навъи мо, варақаҳои параметрҳои мо (барои роҳат мо онҳоро ба ҷои "рӯйхатҳо" "варақҳо" меномем) инҳоянд -
List<String>...stringsLists
- ба массиви варақҳо табдил меёбад - List[]бо навъи номаълум (фаромӯш накунед, ки varargs дар натиҷаи ҷамъоварӣ ба массиви муқаррарӣ табдил меёбад). Аз ин сабаб, мо метавонем ба осонӣ ба тағирёбанда Object[] arrayдар сатри якуми усул супориш диҳем - намудҳо аз варақаҳои мо тоза карда шуданд! Ва ҳоло мо як тағирёбандаи навъи дорем Object[], ки дар он мо метавонем ҳама чизро илова кунем - ҳама an objectҳо дар Java аз Object! Ҳоло мо танҳо як қатор варақҳои сатр дорем. Аммо ба шарофати истифода varargsва нест кардани намудҳо, мо метавонем ба осонӣ як варақи рақамҳоро ба онҳо илова кунем, ки мо ин корро мекунем. Дар натича мо бо омехта кардани an objectхои навъхои гуногун теппаро ифлос мекунем. ClassCastExceptionҲангоми кӯшиши хондани сатр аз массив, натиҷа ҳамон истисно хоҳад буд . Натиҷаи консол:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
Инҳоянд оқибатҳои ғайричашмдоште, ки дар натиҷаи истифодаи механизми ба назар оддӣ ба вуҷуд омада метавонанд varargs:) Ва дар ин ҷо лексияи имрӯзаи мо ба охир мерасад. Якчанд мушкилотро ҳал карданро фаромӯш накунед ва агар шумо вақт ва қувва дошта бошед, адабиёти иловагиро омӯзед. " Effective Java " худашро намехонад! :) То дидор!
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION