JavaRush /جاوا بلاگ /Random-SD /varargs استعمال ڪندي جڏهن generics سان ڪم ڪرڻ

varargs استعمال ڪندي جڏهن generics سان ڪم ڪرڻ

گروپ ۾ شايع ٿيل
سلام! اڄ جي سبق ۾ اسين generics جو مطالعو جاري رکنداسين. بس ائين ئي ٿئي ٿو ته هي هڪ وڏو موضوع آهي، پر هتي وڃڻ لاءِ ڪٿي به ناهي - هي ٻولي جو هڪ انتهائي اهم حصو آهي :) جڏهن توهان پڙهو ٿا Oracle دستاويزن تي جنريڪس يا پڙهو گائيڊس انٽرنيٽ تي، توهان کي شرطن تي نظر ايندي. غير ريفائيبل قسمون ۽ ريفائيبل قسمون . ڪهڙي قسم جو لفظ آهي "Reifiable"؟ توڙي جو سڀ ڪجھ انگريزيءَ سان سٺو آھي، توھان کي ان سان ملڻ جو امڪان ناھي. اچو ته ترجمو ڪرڻ جي ڪوشش ڪريو! varargs استعمال ڪرڻ جڏهن عام سان ڪم ڪرڻ - 2
* گوگل جي مهرباني، توهان تمام گهڻي مدد ڪئي -_-*
ريفائيبل-قسم ھڪڙو قسم آھي جنھن جي معلومات مڪمل طور تي رن ٽائم تي دستياب آھي. جاوا ٻولي ۾، انهن ۾ شامل آهن پرائمري، خام قسم، ۽ غير عام قسم. ان جي ابتڙ، غير ريفائيبل قسم جا قسم آهن جن جي معلومات کي ختم ڪيو ويو آهي ۽ رن ٽائم تي دستياب ناهي. اهي صرف عام آهن - List<String> ، List<Integer> ، وغيره.

رستي جي ذريعي، توهان کي ياد آهي ته varargs ڇا آهن ؟

صورت ۾ توهان وساري ڇڏيو، اهي متغير ڊگھائي دليل آهن. اهي انهن حالتن ۾ هٿ ۾ اچن ٿا جتي اسان کي خبر ناهي ته اسان جي طريقي سان ڪيترا دليل منظور ٿي سگهن ٿا. مثال طور، جيڪڏهن اسان وٽ هڪ ڪليڪٽر ڪلاس آهي ۽ ان ۾ هڪ طريقو آهي 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عامات سان گڏ ميلاپ ۾ استعمال ڪيو وڃي ته ڪجهه اهم خاصيتون آهن. اچو ته هن ڪوڊ کي ڏسو:
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")
       );
   }
}
اهو طريقو هڪ فهرست وٺي ٿو ۽ شيون جو تعداد addAll()ان پٽ جي طور تي ، ۽ پوء انهن سڀني شين کي لسٽ ۾ شامل ڪري ٿو. طريقي ۾ اسان کي اسان جو طريقو ٻه ڀيرا سڏين ٿا . پهريون ڀيرو اسان ٻن باقاعده لائينن ۾ شامل ڪيو. هتي سڀ ڪجهه ٺيڪ آهي. ٻيو ڀيرو اسان ٻن شين ۾ شامل ڪيو . ۽ هتي اسان کي اوچتو هڪ ڊيڄاريندڙ ملي ٿو: List<E>Emain()addAll()ListListPair<String, String>

Unchecked generics array creation for varargs parameter
هن جو ڇا مطلب آهي؟ اسان کي ڊيڄاريندڙ ڇو ملي ٿو ۽ ان سان ڇا ڪرڻو آهي array؟ Array- هي هڪ صف آهي، ۽ اسان جي ڪوڊ ۾ ڪي به صفون نه آهن! اچو ته ٻئي سان شروع ڪريون. ڊيڄاريندڙ هڪ صف جو ذڪر ڪري ٿو ڇاڪاڻ ته مرتب ڪندڙ variable length arguments (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>هي هڪ غير ريفائيبل قسم آهي. تاليف جي دوران، پيٽرولر جي قسمن بابت سڀ معلومات (<String، String>) ختم ٿي ويندي. جاوا ۾ نان ريفائيبل ٽائپ مان صفون ٺاهڻ جي اجازت ناهي . توھان ان جي تصديق ڪري سگھو ٿا جيڪڏھن توھان ڪوشش ڪريو دستي طور ھڪڙو صف ٺاھيو Pair<String, String>
public static void main(String[] args) {

   //  ошибка компиляции! Generic array creation
  Pair<String, String>[] array = new Pair<String, String>[10];
}
سبب واضح آهي - قسم جي حفاظت. جيئن توهان کي ياد آهي، جڏهن هڪ صف ٺاهيندي، توهان کي اهو ظاهر ڪرڻ گهرجي ته ڪهڙيون شيون (يا ابتدائي) هي صف محفوظ ڪندو.
int array[] = new int[10];
پوئين سبقن مان هڪ ۾، اسان تفصيل سان جائزو ورتو ته قسم ختم ڪرڻ واري ميڪانيزم. تنهن ڪري، هن صورت ۾، قسمين کي ختم ڪرڻ جي نتيجي ۾، اسان ان معلومات کي وڃائي ڇڏيو آهي ته Pairجوڙو اسان جي شين ۾ ذخيرو ٿيل هئا <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
سادي اصطلاحن ۾، هيپ آلودگي هڪ اهڙي صورتحال آهي جنهن ۾ قسم 1 جون شيون ڍير تي هجڻ گهرجن А، پر قسم جون شيون اتي ختم ٿي وڃن ٿيون B، قسم جي حفاظت جي غلطين جي ڪري. اسان جي مثال ۾ اهو ئي ٿئي ٿو. پهرين اسان هڪ Raw variable ٺاهيو numbers۽ ان کي هڪ عام مجموعي ۾ لڳايو ArrayList<Number>. ان کان پوء اسان اتي نمبر شامل ڪيو 1.
List<String> strings = numbers;
هن لڪير ۾، مرتب ڪندڙ اسان کي خبرداري جاري ڪندي ممڪن غلطين بابت ڊيڄارڻ جي ڪوشش ڪئي ” ان چيڪ ٿيل اسائنمينٽ... “، پر اسان ان کي نظرانداز ڪيو. نتيجي طور، اسان وٽ ھڪڙو عام متغير آھي قسم جو List<String>ھڪڙو عام مجموعو ڏانھن اشارو ڪري ٿو قسم جي ArrayList<Number>. اها صورتحال واضح طور تي مصيبت پيدا ڪري سگهي ٿي! ائين ئي ٿئي ٿو. اسان جي نئين متغير کي استعمال ڪندي، اسان گڏ ڪرڻ لاء هڪ اسٽرنگ شامل ڪندا آهيون. هيپ آلوده ٿي چڪو هو - اسان ٽائپ ڪيل مجموعي ۾ پهريون نمبر ۽ پوءِ هڪ تار شامل ڪيو. مرتب ڪندڙ اسان کي ڊيڄاريو، پر اسان ان جي ڊيڄاريندڙ کي نظر انداز ڪيو، ClassCastExceptionصرف نتيجا حاصل ڪري رهيا هئاسين جڏهن پروگرام هلندي هئي. ان سان ڪهڙو تعلق آهي varargs؟ generics سان استعمال ڪرڻ 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);
   }
}
هتي ڇا ٿي رهيو آهي؟ ٽائپ erasure جي ڪري، اسان جي پيراميٽر شيٽ (اسان انهن کي سھولت لاءِ ”لسٽن“ بدران ”شيٽس“ سڏينداسين) ھي آھن -
List<String>...stringsLists
- شيٽ جي هڪ صف ۾ بدلجي ويندي - List[]اڻڄاتل قسم سان (اهو نه وساريو ته varargs تاليف جي نتيجي ۾ باقاعده صف ۾ بدلجي ٿو). انهي جي ڪري، اسان آساني سان طريقي جي پهرين لائن ۾ هڪ متغير کي تفويض ڪري سگهون ٿا Object[] array- قسم اسان جي شيٽ مان ختم ٿي ويا آهن! ۽ ھاڻي اسان وٽ ھڪڙي قسم جو متغير آھي Object[]، جتي اسان ڪجھ به شامل ڪري سگھون ٿا - جاوا ۾ سڀ شيون ورثي ۾ Object! هن وقت اسان وٽ صرف اسٽرنگ شيٽ جو هڪ سلسلو آهي. پر قسمن جي استعمال varargs۽ ختم ڪرڻ جي مهرباني، اسان آساني سان انهن ۾ انگن جي هڪ شيٽ شامل ڪري سگهون ٿا، جيڪو اسان ڪندا آهيون. نتيجي طور، اسان مختلف قسمن جي شين کي گڏ ڪندي ڍير کي آلوده ڪريون ٿا. نتيجو ساڳيو استثنا هوندو ClassCastExceptionجڏهن صف مان هڪ اسٽرنگ پڙهڻ جي ڪوشش ڪئي ويندي. ڪنسول آئوٽ:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
اهي اڻڄاتل نتيجا آهن جيڪي هڪ بظاهر سادو ميڪانيزم استعمال ڪرڻ جا نتيجا آهن varargs:) ۽ هي اهو آهي جتي اسان جو ليڪچر اڄ ختم ٿئي ٿو. ڪجھ مسئلا حل ڪرڻ نه وساريو، ۽ جيڪڏھن توھان وٽ وقت ۽ توانائي آھي، اضافي ادب جو مطالعو ڪريو. ” اثر جاوا “ پاڻ نه پڙهندو! :) ملندا سين!
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION