JavaRush /Java Blog /Random-KO /Java 개발자가 흔히 저지르는 10가지 실수
theGrass
레벨 24
Саратов

Java 개발자가 흔히 저지르는 10가지 실수

Random-KO 그룹에 게시되었습니다
Java 개발자가 자주 범하는 실수 10가지 - 1
이 목록에는 Java 개발자가 자주 범하는 10가지 실수가 포함되어 있습니다.
  1. 배열을 ArrayList 로 변환합니다 .

    배열을 ArrayList 로 변환하기 위해 개발자는 종종 다음 방법을 사용합니다.

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

    Arrays.asList()클래스의 ArrayList내부 전용 정적 클래스인 클래스 객체를 반환하며 이는 클래스 가 아닙니다 . 클래스에는 ,, , 메서드가 포함되어 있지만 요소를 추가하는 메서드는 포함되어 있지 않으며 크기가 고정되어 있습니다 . 실제를 만들려면 다음을 수행하십시오.(private static class)Arraysjava.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.Serialized를 구현합니다).

  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사용하면 안 됩니다 .HashtableHashMap

    해시맵과 해시맵 트리맵 대 해시테이블과 해시테이블 비교 LinkedHashMap .

    지도 인터페이스에 관한 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

    Java 개발자가 자주 범하는 실수 10가지 - 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의 인기 쿼리에 대한 분석을 기반으로 합니다. 나는 그것이 실제로 가장 심각한 10가지 실수에 속한다고 증명할 수는 없지만 실제로는 매우 흔한 실수입니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION