JavaRush /Blog Java /Random-MS /10 Kesilapan Yang Sering Dibuat oleh Pembangun Java
theGrass
Tahap
Саратов

10 Kesilapan Yang Sering Dibuat oleh Pembangun Java

Diterbitkan dalam kumpulan
10 kesilapan yang sering dilakukan oleh pembangun Java - 1
Senarai ini termasuk 10 kesilapan yang sering dilakukan oleh pembangun Java .
  1. Menukar tatasusunan kepada ArrayList .

    Untuk menukar tatasusunan kepada ArrayList , pembangun sering menggunakan kaedah ini:

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

    Arrays.asList()akan mengembalikan objek kelas ArrayListyang merupakan kelas statik peribadi dalaman (private static class)kelas Arrays, dan ini bukan kelas java.util.ArrayList.Kelas java.util.Arrays.ArrayListmengandungi kaedah set(), get(), contains(), tetapi tidak mengandungi sebarang kaedah untuk menambah elemen, saiznya tetap . Untuk mencipta yang sebenar java.util.ArrayList, lakukan ini:

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

    Pembina kelas java.util.ArrayListboleh mengambil sebagai parameter semua objek yang melaksanakan antara muka Collection, pelaksanaan yang diwarisi oleh kelasjava.util.Arrays.ArrayList

    (kelas statik peribadi ArrayList<E> memanjangkan AbstractList<E> melaksanakan RandomAccess, java.io.Serializable).

  2. Menyemak tatasusunan untuk nilai tertentu.

    Pemaju sering melakukan ini:

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

    Kod ini berfungsi, tetapi tidak perlu menukarnya Listkepada Set. Menukar kepada Setakan mengambil masa tambahan. Sebenarnya, semuanya mudah:

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

    atau

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

    Kaedah pertama adalah lebih pendek.

  3. Mengalih keluar elemen dari Listdalam gelung

    Pertimbangkan kod berikut yang mengalih keluar elemen dalam gelung:

    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);

    Kesimpulan:

    [b, d]

    Ini ternyata satu kesilapan yang serius. Apabila elemen dialih keluar, saiznya Listdikurangkan dan indeks elemen berubah.

    Jadi elakkan kaedah ini jika anda ingin mengalih keluar berbilang elemen dalam gelung menggunakan indeks.

    Anda mungkin tahu bahawa menggunakan iterator ialah penyelesaian yang betul untuk mengalih keluar elemen dalam gelung, dan anda tahu bahawa gelung gaya for-eachberfungsi seperti lelaran, tetapi tidak.

    Pertimbangkan kod berikut:

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

    Kami akan menerima ConcurrentModificationException .

    Perkara yang betul untuk dilakukan ialah:

    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();
    	}
    }

    Kaedah next()mesti dipanggil sebelum remove().

    Dalam gaya gelung for-each, pengkompil akan memanggil kaedah remove(), dan hanya kemudian next(), yang akan menimbulkan ralat ConcurrentModificationException. Anda boleh melihat kod ArrayList.iterator().

  4. Hashtableterhadap HashMap.

    Disebabkan oleh pelaksanaan yang sepadan, Hashtable ialah nama struktur data.

    Tetapi dalam Java nama untuk struktur data ialah HashMap. Salah satu perbezaan utama antara Hashtabledan HashMapialah ia Hashtabledisegerakkan. Jadi ia tidak boleh digunakan Hashtabledi mana HashMap.

    HashMap lwn. TreeMap lwn. Hashtable lwn. LinkedHashMap .

    10 soalan asas tentang antara muka Peta

  5. Gunakan koleksi tanpa sekatan kandungan

    В 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 kesilapan yang sering dilakukan oleh pembangun Java - 2

    Ralat kompilasi ini disebabkan oleh fakta bahawa kelas nenek moyang tidak mempunyai pembina lalai yang ditentukan. Dalam Java , melainkan anda menentukan sendiri pembina kelas, pengkompil akan mencipta pembina lalai yang tidak memerlukan hujah. Jika pembina diterangkan dalam kelas Supersebagai Super(String s){}, pengkompil itu sendiri tidak akan menambah apa-apa. Inilah yang kita lihat dalam contoh kita.

    Pembina kelas Sub, tidak kira yang mana satu, akan memanggil pembina lalai kelas Super, kerana tiada perkara lain yang ditentukan. Oleh kerana tiada pembina lalai dalam class Super, ini akan membawa kepada ralat kompilasi.

    Penyelesaian pertama untuk masalah ini ialah menambah pembina lalai ke kelasSuper

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

    Pilihan kedua ialah untuk mengalih keluar pembina yang kami huraikan daripada kelas Supersupaya pengkompil mencipta pembina lalai.

    Dan pilihan terakhir ialah menambah panggilan super(value)kepada pembina kelas Subsupaya pembina kelas sedia ada dipanggil dan bukannya pembina lalaiSuper

    Pembina Super dan Sub

  10. " " atau pembina?

    Terdapat dua cara untuk membuat rentetan:

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

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

    Apakah perbezaan antara mereka?

    Anda boleh memahami ini daripada contoh berikut:

    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

    Untuk mengetahui lebih lanjut tentang cara rentetan disimpan dalam ingatan, baca Cipta Rentetan Java Menggunakan "" atau Pembina? .

Rancangan masa hadapan. Senarai ini berdasarkan analisis saya terhadap sejumlah besar projek Sumber Terbuka daripada GitHub, soalan daripada Stack Overflow dan pertanyaan popular di Google. Saya tidak menganggap untuk membuktikan bahawa mereka benar-benar antara sepuluh kesilapan yang paling serius, tetapi mereka sebenarnya sangat biasa.
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION