JavaRush /Java Blog /Random-IT /10 errori spesso commessi dagli sviluppatori Java
theGrass
Livello 24
Саратов

10 errori spesso commessi dagli sviluppatori Java

Pubblicato nel gruppo Random-IT
10 errori spesso commessi dagli sviluppatori Java - 1
Questo elenco include 10 errori spesso commessi dagli sviluppatori Java .
  1. Conversione di un array in un ArrayList .

    Per convertire un array in un ArrayList , gli sviluppatori utilizzano spesso questo metodo:

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

    Arrays.asList()restituirà un oggetto di classe ArrayListche è una classe statica privata interna (private static class)della classe Arrayse questa non è una classe. java.util.ArrayList.La classe java.util.Arrays.ArrayListcontiene metodi set(), get(), contains(), ma non contiene alcun metodo per aggiungere elementi, la sua dimensione è fissa . Per crearne uno vero java.util.ArrayList, fai questo:

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

    Un costruttore di classe java.util.ArrayListpuò prendere come parametro tutti gli oggetti che implementano un'interfaccia Collection, la cui implementazione è ereditata dalla classejava.util.Arrays.ArrayList

    (la classe statica privata ArrayList<E> estende AbstractList<E> implementa RandomAccess, java.io.Serializable).

  2. Controllo di un array per un valore specifico.

    Gli sviluppatori spesso fanno così:

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

    Il codice funziona, ma non è necessario convertirlo Listin Set. La conversione in Setrichiederà più tempo. In effetti, tutto è semplice:

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

    O

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

    Il primo metodo è molto più breve.

  3. Rimozione di un elemento da Listun ciclo

    Considera il seguente codice che rimuove gli elementi in un ciclo:

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

    Conclusione:

    [b, d]

    Questo si rivela un grave errore. Quando un elemento viene rimosso, la dimensione Listviene ridotta e gli indici dell'elemento cambiano.

    Quindi evita questo metodo se desideri rimuovere più elementi in un ciclo utilizzando un indice.

    Potresti sapere che l'utilizzo di un iteratore è la soluzione corretta per rimuovere elementi in un ciclo e sai che un ciclo di stile for-eachfunziona come un iteratore, ma non è così.

    Considera il seguente codice:

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

    Riceveremo una ConcurrentModificationException .

    La cosa corretta da fare è:

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

    Il metodo next()deve essere chiamato prima del remove().

    In uno stile loop for-each, il compilatore chiamerà il metodo remove()e, solo allora next(), genererà un errore ConcurrentModificationException. Puoi guardare il codice ArrayList.iterator().

  4. Hashtablecontro HashMap.

    A causa della corrispondente implementazione, Hashtable è il nome della struttura dati.

    Ma in Java il nome di una struttura dati è HashMap. Una delle differenze principali tra Hashtablee HashMapè che è Hashtablesincronizzato, quindi non dovrebbe essere utilizzato Hashtabledove HashMap.

    HashMap vs. Mappa ad albero vs. Tabella hash vs. LinkedHashMap .

    10 domande fondamentali sull'interfaccia della mappa

  5. Utilizza le raccolte senza restrizioni sui contenuti

    В 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 errori spesso commessi dagli sviluppatori Java - 2

    Questo errore di compilazione è causato dal fatto che la classe antenata non ha un costruttore predefinito definito. In Java , a meno che tu non specifichi tu stesso un costruttore di classe, il compilatore creerà un costruttore predefinito che non richiede argomenti. Se il costruttore è descritto nella classe Supercome Super(String s){}, il compilatore stesso non aggiungerà nulla. Questo è ciò che vediamo nel nostro esempio.

    Il costruttore della classe Sub, non importa quale, chiamerà il costruttore predefinito della classe Super, poiché non è specificato nient'altro. Poiché non esiste un costruttore predefinito nella classe Super, ciò porterà a un errore di compilazione.

    La prima soluzione a questo problema è aggiungere un costruttore predefinito alla classeSuper

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

    La seconda opzione è rimuovere il costruttore descritto dalla classe Superin modo che il compilatore crei un costruttore predefinito.

    E l'ultima opzione è aggiungere una chiamata super(value)ai costruttori di classe Subin modo che venga chiamato il costruttore di classe esistente invece del costruttore predefinitoSuper

    Costruttore di Super e Sub

  10. " " o costruttore?

    Esistono due modi per creare una stringa:

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

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

    Qual'è la differenza tra loro?

    Puoi capirlo dai seguenti esempi:

    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

    Per ulteriori informazioni su come le stringhe vengono archiviate in memoria, leggi Creare una stringa Java utilizzando "" o Costruttore? .

Progetti futuri. Questo elenco si basa sulla mia analisi di un numero enorme di progetti Open Source di GitHub, domande di Stack Overflow e query popolari su Google. Non ho la presunzione di dimostrare che siano davvero tra i dieci errori più gravi, ma in realtà sono molto comuni.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION