티스토리 뷰

 

아래 글은 Top 10 Mistakes Java Developers Make 번역본이며 일부 첨언을 하였다.

 

4. Hashtable VS HashMap


Map 인터페이스에 HashMap, TreeMap, Hashtable, LinkedHashMap이 정의되어 있다.

Hashtable은 알고리즘 규칙에 의한 자료구조 이름이다. 그러나 자바(Java)에서는 HashMap으로 정의되었다.

Hashtable과 HashMap의 주요 차이점 중 하나는 Hashtable은 동기화(synchronized)가 된다는 것이다.

  • HashMap : Hashtable로 구현되었으며, key 또는 value에 대한 정렬은 없다.
  • TreeMap : red-black tree(이진트리의 특수한 형태) 구조를 기반으로 구현되었으며 키로 순서를 정한다.
  • LinkedHashMap : LinkedHashMap은 삽입 순서를 보존한다.
  • HashTable : HashMap과 대조적으로 동기화된다. thread-safe 라면 HashMap을 사용해야 하는 이유이다.

 

5. Use Raw Type of Collection


Java에서는 raw Type과 unbounded wildcard type이 쉽게 함께 사용된다. Set을 예로 들어보면 Set은 raw type이고 Set<?>은 unbounded wildcard type이다.

 

다음과 같이 raw type 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);

}

// Exception

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

raw type collection을 사용하는 것은 타입 체크를 건너뛰기 때문에 안전하지 않다.

 

6. Access Level


개발자들은 습관적으로 또는 알면서도 public 클래스 필드를 사용한다. 외부에서 아주 간단하게 필드 값에 접근을 할 수 있지만, 이건 아주 안 좋은 설계이다. 가능한 최대한 레벨을 낮추어 접근을 막도록 하자. 우리 모두 학교 또는 학원에서 객체지향의 특징과 캡슐화에 대해 배웠다는 것을 잊지 말자.

 

7. ArrayList VS LinkedList


ArrayList와 LinkedList의 차이를 모를 때 종종 그냥 익숙해 보이는 ArrayList를 사용한다. 어떤 걸 사용하든 같은 결과를 보여주기 때문에 더더욱 차이점을 알기 힘들다. 하지만 둘 사이에는 큰 성능의 차이가 존재한다. LinkedList는 많은 양의 추가/삭제 연산 및 임의 접근(Random Access)이 적을 경우에 더 빠른 성능을 보인다.

 

시간복잡도 비교는 다음과 같다.

 

 

8. Mutable VS Immutable


Immutable 객체는 심플하고, 안전성 등에서 많은 장점을 가지고 있다. 그러나 각각 다른 값을 새로운 객체에 생성해야 하고 그런 이유로 GC(garbage collection)에 큰 부하를 줄 가능성이 있다. 필요에 따라 mutable 과 immutable 중 잘 선택해야 한다.

일반적으로 mutable 객체는 하나의 객체를 만들기 위해 값을 많이 바꿀 필요가 있을 경우에 사용한다. 예를 들어 많은 문자열(String)을 이어붙여야 할 경우 immutable 문자열을 사용한다면 매번 문자열을 이을 때마다 불필요한 객체가 생성될 것이다. 이것은 쓸데없는 CPU의 시간과 에너지를 소비시킨다. 이런 곳에서는 mutable 객체를 사용하는 것이 바람직하다.(ex : StringBuilder)

String result = "";

for (String s : arr) {

result += s;

}

StringBuilder builder = new StringBuilder(""); for (String s : arr) {

builder.append(s);

}

 

 

9. Constructor of Super and Sub

 

 


 

 

 

위의 컴파일 에러는 Super의 기본 생성자가 정의되어 있지 않기 때문이다. 자바(Java)에서는 생성자가 없는 클래스가 있다면 컴파일러가 자동으로 디폴트 생성자를 생성해준다. 만약 개발자가 매개변수를 받는 생성자를 정의했다면 컴파일러가 자동으로 디폴트 생성자를 만들어 주지 않는다. 이 상황이 바로 위의 Super 클래스의 상황이다.

위의 두 Sub 클래스의 생성자는 Super 클래스의 디폴트 생성자를 호출할 것이다. 컴파일러는 Sub 클래스의 생성자 내부에 super()를 자동으로 추가하지만 Super 클래스의 디폴트 생성자는 존재하지 않기 때문에 에러가 발생된다.

 

해결방법으로는

  1. Super() 생성자를 Super 클래스에 추가
  2. 정의 되어 있는 Super 클래스의 생성자를 제거
  3. Sub 클래스 생성자에 super(value)를 명시적으로 추가

 

10. "" or Constructor?


문자열은 크게 2가지 방법으로 생성할 수 있다.

 

아래의 예제에서 2가지 방법의 차이를 알 수 있다.

Constuctor로 문자열을 생성할 때는 같은문자열이여도 새로운 메모리가 할당되며, ""로 생성할 때는 같은 값일 경우 이미 할당된 값의 메모리 값을 참조하게 된다.

// 1. use double quotes String a = "abcd"; String b = "abcd"; System.out.println(a == b); // true System.out.println(a.equals(b)); // true // 2. use constructor String c = new String("abcd"); String d = new String("abcd"); System.out.println(c == d); // false System.out.println(c.equals(d)); // true

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함