JavaRush /Java Blog /Random-TK /Generika bilen işlän wagtyňyz varargs ulanmak

Generika bilen işlän wagtyňyz varargs ulanmak

Toparda çap edildi
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ň! Generika bilen işlän wagtyňyz varargs ulanmak - 2
* 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 bar sum. 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 varargskä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>Emain()addAll()ListListPair<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 Pairjü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, varargsdüşü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. Generika bilen işlän wagtyňyz varargs ulanmak - 4Hapalanma 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 . BMysalymyzda şeýle bolýar. Ilki bilen çig üýtgeýjini döretdik numberswe 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 ClassCastExceptiondiň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 varargsaň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. ClassCastExceptionToplumdan 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!
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION