JavaRush /Blogue Java /Random-PT /10 erros frequentemente cometidos por desenvolvedores Jav...
theGrass
Nível 24
Саратов

10 erros frequentemente cometidos por desenvolvedores Java

Publicado no grupo Random-PT
10 erros frequentemente cometidos por desenvolvedores Java - 1
Esta lista inclui 10 erros que os desenvolvedores Java costumam cometer.
  1. Convertendo um array em um ArrayList .

    Para converter um array em ArrayList , os desenvolvedores costumam usar este método:

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

    Arrays.asList()retornará um objeto de classe ArrayListque é uma classe estática privada interna (private static class)da classe Arrays, e esta não é uma classe. java.util.ArrayList.A classe java.util.Arrays.ArrayListcontém métodos ,,,, set()mas não contém nenhum método para adicionar elementos, seu tamanho é fixo . Para criar um real , faça o seguinte:get()contains()java.util.ArrayList

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

    Um construtor de classe java.util.ArrayListpode tomar como parâmetro todos os objetos que implementam uma interface Collection, cuja implementação é herdada pela classejava.util.Arrays.ArrayList

    (classe estática privada ArrayList<E> estende AbstractList<E> implementa RandomAccess, java.io.Serializable).

  2. Verificando uma matriz em busca de um valor específico.

    Os desenvolvedores costumam fazer isso:

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

    O código funciona, mas não há necessidade de convertê-lo Listpara Set. A conversão para Setlevará mais tempo. Na verdade, tudo é simples:

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

    ou

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

    O primeiro método é muito mais curto.

  3. Removendo um elemento de Listum loop

    Considere o seguinte código que remove elementos de um loop:

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

    Conclusão:

    [b, d]

    Isso acaba sendo um erro grave. Quando um elemento é removido, o tamanho Listé reduzido e os índices do elemento mudam.

    Portanto, evite esse método se quiser remover vários elementos em um loop usando um índice.

    Você deve saber que usar um iterador é a solução correta para remover elementos em um loop e sabe que um loop de estilo for-eachfunciona como um iterador, mas não funciona.

    Considere o seguinte código:

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

    Receberemos uma ConcurrentModificationException .

    A coisa correta a fazer é:

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

    O método next()deve ser chamado antes do remove().

    Em um estilo loop for-each, o compilador chamará o método remove(), e só então next(), o que gerará um erro ConcurrentModificationException. Você pode olhar o código ArrayList.iterator().

  4. Hashtablecontra HashMap.

    Devido à implementação correspondente, Hashtable é o nome da estrutura de dados.

    Mas em Java o nome de uma estrutura de dados é HashMap. Uma das principais diferenças entre Hashtablee HashMapé que ele é Hashtablesincronizado, portanto não deve ser usado Hashtableonde HashMap.

    HashMap vs. TreeMap vs. Tabela hash vs. LinkedHashMap .

    10 perguntas básicas sobre a interface do Mapa

  5. Use coleções sem restrições de conteúdo

    В 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 erros frequentemente cometidos por desenvolvedores Java - 2

    Este erro de compilação é causado pelo fato da classe ancestral não possuir um construtor padrão definido. Em Java , a menos que você mesmo especifique um construtor de classe, o compilador criará um construtor padrão que não requer argumentos. Se o construtor for descrito na classe Supercomo Super(String s){}, o próprio compilador não adicionará nada. Isto é o que vemos em nosso exemplo.

    O construtor da classe Sub, não importa qual, chamará o construtor padrão da classe Super, já que nada mais é especificado. Como não há construtor padrão na classe Super, isso causará um erro de compilação.

    A primeira solução para este problema é adicionar um construtor padrão à classeSuper

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

    A segunda opção é remover o construtor que descrevemos da classe Superpara que o compilador crie um construtor padrão.

    E a última opção é adicionar uma chamada super(value)aos construtores de classe Subpara que o construtor de classe existente seja chamado em vez do construtor padrãoSuper

    Construtor de Super e Sub

  10. " " ou construtor?

    Existem duas maneiras de criar uma string:

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

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

    Qual a diferença entre eles?

    Você pode entender isso a partir dos seguintes exemplos:

    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

    Para saber mais sobre como as strings são armazenadas na memória, leia Criar string Java usando "" ou Construtor? .

Planos futuros. Esta lista é baseada na minha análise de um grande número de projetos de código aberto do GitHub, perguntas do Stack Overflow e consultas populares no Google. Não pretendo provar que eles estão realmente entre os dez erros mais graves, mas na verdade são muito comuns.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION