JavaRush /مدونة جافا /Random-AR /10 أخطاء غالبًا ما يرتكبها مطورو جافا
theGrass
مستوى
Саратов

10 أخطاء غالبًا ما يرتكبها مطورو جافا

نشرت في المجموعة
10 أخطاء يرتكبها مطورو Java غالبًا - 1
تتضمن هذه القائمة 10 أخطاء يرتكبها مطورو Java غالبًا.
  1. تحويل مصفوفة إلى ArrayList .

    لتحويل مصفوفة إلى ArrayList ، غالبًا ما يستخدم المطورون هذه الطريقة:

    List<String> list = Arrays.asList(arr);

    Arrays.asList()سيُرجع كائن فئة ArrayListوهو فئة ثابتة داخلية خاصة (private static class)للفئة Arrays، وهذه ليست فئة. تحتوي java.util.ArrayList.الفئة على أساليب ، و ، ولكنها لا تحتوي على أي أساليب لإضافة عناصر، وحجمها ثابت . لإنشاء واحدة حقيقية ، قم بما يلي:java.util.Arrays.ArrayListset()get()contains()java.util.ArrayList

    ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));

    يمكن لمنشئ الفئة java.util.ArrayListأن يأخذ كمعلمة جميع الكائنات التي تنفذ واجهة ما Collection، والتي يتم وراثة تنفيذها بواسطة الفئةjava.util.Arrays.ArrayList

    (الفئة الثابتة الخاصة ArrayList<E> تمتد AbstractList<E> وتنفذ RandomAccess، java.io.Serializable).

  2. التحقق من صفيف لقيمة محددة.

    غالبًا ما يفعل المطورون هذا:

    Set<String> set = new HashSet<String>(Arrays.asList(arr));
    return set.contains(targetValue);

    الكود يعمل ولكن ليست هناك حاجة لتحويله Listإلى Set. Setسيستغرق التحويل إلى وقتًا إضافيًا. في الواقع، كل شيء بسيط:

    Arrays.asList(arr).contains(targetValue);

    أو

    for(String s: arr){
    	if(s.equals(targetValue))
    		return true;
    }
    return false;

    الطريقة الأولى أقصر بكثير.

  3. إزالة عنصر من Listداخل حلقة

    خذ بعين الاعتبار الكود التالي الذي يزيل العناصر في الحلقة:

    ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
    for (int i = 0; i < list.size(); i++) {
    	list.remove(i);
    }
    System.out.println(list);

    خاتمة:

    [b, d]

    تبين أن هذا خطأ فادح. عند إزالة عنصر ما، يتم تقليل الحجم Listوتتغير مؤشرات العنصر.

    لذا تجنب هذه الطريقة إذا كنت تريد إزالة عناصر متعددة في حلقة باستخدام فهرس.

    ربما تعلم أن استخدام المكرر هو الحل الصحيح لإزالة العناصر في الحلقة، كما تعلم أن حلقة النمط for-eachتعمل مثل المكرر، لكنها لا تفعل ذلك.

    خذ بعين الاعتبار الكود التالي:

    ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
    
    for (String s : list) {
    	if (s.equals("a"))
    		list.remove(s);
    }

    سوف نتلقى ConcurrentModificationException .

    الشيء الصحيح الذي يجب فعله هو:

    ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
    Iterator<String> iter = list.iterator();
    while (iter.hasNext()) {
    	String s = iter.next();
    
    	if (s.equals("a")) {
    		iter.remove();
    	}
    }

    يجب أن يتم استدعاء الأسلوب next()قبل remove().

    في نمط الحلقة for-each، سيستدعي المترجم الطريقة remove()، وعندها فقط next()، سيؤدي ذلك إلى حدوث خطأ ConcurrentModificationException. يمكنك إلقاء نظرة على الكود ArrayList.iterator().

  4. Hashtableضد HashMap.

    نظرًا للتنفيذ المقابل، فإن Hashtable هو اسم بنية البيانات.

    ولكن في Java اسم بنية البيانات هو HashMap. أحد الاختلافات الرئيسية بين Hashtableو HashMapهو أنه Hashtableمتزامن، لذلك لا ينبغي استخدامه Hashtableحيث HashMap.

    هاشماب مقابل. خريطة الشجرة مقابل. جدول التجزئة مقابل. لينكيدهاش ماب .

    10 أسئلة أساسية حول واجهة الخريطة

  5. استخدم المجموعات دون قيود المحتوى

    В Java часто путают коллекции без ограничений по содержимому, и коллекции с маской по типу содержимого. К примеру, для множеств - Set это коллекция без ограничений по содержимому, а Set<?> — коллекция у которой все-таки есть ограничения, но эти ограничения ничего на самом деле не ограничивают. Рассмотрим следующий code, где List без ограничений используется в качестве параметра метода:

    public static void add(List list, Object o){
    	list.add(o);
    }
    public static void main(String[] args){
    	List<String> list = new ArrayList<String>();
    	add(list, 10);
    	String s = list.get(0);
    }

    Данный code выбросит исключение:

    Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    	at …

    Использование коллекций без ограничений по содержимому очень опасно, потому что вы не можете быть уверенными в том что там лежит внутри. А для того чтобы понять всю глубину разницы между Set, Set<?> и Set<Object> — почитайте вот эту и эту ссылки.

  6. Уровень доступа

    Очень часто для полей класса разработчики используют модификатор доступа public. Так проще получить meaning поля напрямую. Правильнее использовать How можно более ограниченный доступ к членам класса.

    public, default, protected, and private.

  7. ArrayList против LinkedList

    Когда разработчики не знают чем отличается ArrayList от LinkedList, они используют первый в силу его большей известности. Однако, есть огромная разница в производительности между ними. На самом деле, выбор между ними должен быть продиктован их внутренними особенностями — ArrayList позволяет быстро производить доступ к произвольному элементу массива, а LinkedList — быстро добавлять/удалять элементы в массиве. Почитайте статью по ссылке ArrayList vs. LinkedList чтобы понять причины их разной производительности.

  8. Mutable (Изменяемый) против Immutable (Неизменяемый)

    Неизменяемый an object имеет много преимуществ: простота, безопасность и т.д. Но он требует отдельного an object для каждого нового значения, и за слишком большое количество an objectов придется заплатить понижением производительности. Должен быть баланс при выборе между изменяемым и неизменяемым обьектом.

    В основном чтобы избежать подготовки промежуточных an objectов используется изменяемый an object. Один из классических примеров это конкатенация большого количества строк. Если вы используете неизменяемый an object типа String, то вы создаете много an objectов, которые сразу попадут в сборщик мусора. Это тратит время и энергию процессора, поэтому правильное решение это использование изменяемых обьектов (например StringBuilder).

    String result="";
    for(String s: arr){
    	result = result + s;
    }

    Еще один пример использования изменяемых an objectов — передача такого an object в метод. Это позволит вернуть результат в нем же, без создания лишних an objectов. При работе с an objectми большого размера, к примеру коллекциями, передача коллекции в метод для сортировки и возвращение результата в другой коллекции приводит к совершенно излишнему расходу ресурсов. (Ответ пользователя dasblinkenlight на Stack Overflow).

    Почему an object класса String неизменяем?

  9. Конструкторы классов Super и Sub

    10 أخطاء يرتكبها مطورو Java غالبًا - 2

    يحدث خطأ الترجمة هذا بسبب حقيقة أن فئة السلف لا تحتوي على مُنشئ افتراضي محدد. في Java ، ما لم تحدد مُنشئ فئة بنفسك، فسيقوم المترجم بإنشاء مُنشئ افتراضي لا يتطلب أي وسائط. إذا تم وصف المنشئ في الفصل Superكـ Super(String s){}، فلن يضيف المترجم نفسه أي شيء. وهذا ما نراه في مثالنا.

    منشئ الفئة Sub، بغض النظر عن أي منها، سوف يستدعي المُنشئ الافتراضي للفئة Super، حيث لم يتم تحديد أي شيء آخر. نظرًا لعدم وجود مُنشئ افتراضي في الفصل Super، سيؤدي ذلك إلى حدوث خطأ في الترجمة.

    الحل الأول لهذه المشكلة هو إضافة مُنشئ افتراضي إلى الفصلSuper

    public Super(){
        System.out.println("Super");
    }

    الخيار الثاني هو إزالة المُنشئ الذي وصفناه من الفصل Superبحيث يقوم المترجم بإنشاء مُنشئ افتراضي.

    والخيار الأخير هو إضافة استدعاء super(value)لمنشئي الفئة Subبحيث يتم استدعاء منشئ الفئة الموجود بدلا من المنشئ الافتراضيSuper

    منشئ السوبر والفرعية

  10. "" أو منشئ؟

    هناك طريقتان لإنشاء سلسلة:

    //1. использовать двойные кавычки
    String x = "abc";

    //2. использовать конструктор
    String y = new String("abc");

    ما الفرق بينهم؟

    ويمكنك فهم ذلك من الأمثلة التالية:

    String a = "abcd";
    String b = "abcd";
    System.out.println(a == b);  // True
    System.out.println(a.equals(b)); // True
    
    String c = new String("abcd");
    String d = new String("abcd");
    System.out.println(c == d);  // False
    System.out.println(c.equals(d)); // True

    لمعرفة المزيد حول كيفية تخزين السلاسل في الذاكرة، اقرأ إنشاء سلسلة Java باستخدام "" أو المُنشئ؟ .

خطط مستقبلية. تعتمد هذه القائمة على تحليلي لعدد كبير من المشاريع مفتوحة المصدر من GitHub، والأسئلة من Stack Overflow، والاستعلامات الشائعة على Google. ولا أفترض أن أثبت أنها بالفعل من بين الأخطاء العشرة الأكثر خطورة، لكنها في الواقع شائعة جدًا.
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION