일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- ddd
- 비트마스크
- 다익스트라
- spring security
- 자바
- 파이썬
- Redis
- UML
- 세그먼트 트리
- docker
- series
- 알고리즘
- disjoint set
- equals
- pandas
- JPA
- 문자열
- 데이터 flow
- 위상정렬
- 포트앤어댑터 아키텍처
- 백준
- BFS
- dataframe
- DP
- springboot
- java
- 이펙티브 자바
- 헥사고날 아키텍처
- dfs
- 스프링
- Today
- Total
코딩못하는사람
아이템40,41] @Override 애너테이션,마커 인터페이스 본문
아이템40]@Override 애너테이션을 일관되게 사용하라.
@Override 애너테이션은 상위 타입 메서드를 재정의했음을 알려준다. 이 애너테이션을 일관되게 사용하면 여러가지 악명높은 버그를 예방해준다.
public class Bigram {
private final char first;
private final char second;
public Bigram(char first, char second) {
this.first = first;
this.second = second;
}
public boolean equals(Bigram b) {
return b.first == first && b.second == second;
}
public int hashCode() {
return 31 * first + second;
}
public static void main(String[] args) {
Set<Bigram> s = new HashSet<>();
for (int i = 0; i < 10; i++)
for (char ch = 'a'; ch <= 'z'; ch++)
s.add(new Bigram(ch, ch));
System.out.println(s.size());
}
}
코드를 살펴보면 set자료형이라 26이 출력될 것이라고 생각할 수 있지만 260이 출력된다.
Bigram을 set자료형에 사용하기 위해서 equals를 정의해주었지만 이건 overriding(재정의)한 것이 아니라 overloading(다중정의)한 것이다.
따라서 상위 클래스의 매서드를 재정의하려는 모든 메서드에 @Override 애너테이션을 달아주자(손해보는게 없다).
@Override 애너테이션의 장점
- Overriding을 Overloading로 잘못 작성할 수 있는 오류를 방지 할 수 있다.
- 잘못 작성 했을 경우, 컴파일시 컴파일러가 잘못된 부분을 명확히 알려준다.
달아주지 않아도 되는 한가지 예외는 구체클래스에서 상위 클래스의 추상메서드를 재정의한 경우에는 괜찮다.(달아도 괜찮다)
아이템 41]정의하려는 것이 타입이라면 마커 인터페이스를 사용하라.
마커 인터페이스란?
마커 인터페이스(marker interface) : 아무 메서드도 담고 있지 않고, 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해주는 인터페이스
public interface Serializable{
}
이 Serializable 은 자신을 구현한 클래스의 인터페이스는 ObjectOutputStream을 통해서 직렬화를 write할 수 있다는 것을 알려준다.
마커 인터페이스 vs마커 애너테이션
1.마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 구분하는 타입으로 쓸 수 있으나,마커 애너테이션은 아니다.
마커 인터페이스는 타입이 되기 때문에 애니테이션을 사용했으면 런타임에 발견될 오유를 컴파일시점에 알 수 있다.
ex)ObjectOutputStream.write 메서드는 Object객체를 받도록 설계 되어있는데 직렬화 불가능한 객체를 넘겨도 애너테이션을 사용하면 런타임에 발견된다.
2.마커 인터페이스는 적용 대상을 더 정밀하게 지정할 수 있다.
적용대상을 ElementType.TYPE로 선언한 애너테이션은 모든타입(클래스,인터페이스,열거형,애너테이션)에 달 수 있다. 이말은 부착할 수 있는 타입을 세밀하게 제한하지 못한다는 뜻이다.
특정 인터페이스를 구현한 클래스에만 적용하고 싶은 마커가 있다면 마커 인터페이스를 사용하자.
ex)set 인터페이스도 일종의 마커 인터페이스다. set은 Collection의 하위 타입에만 적용할 수 있기 때문이다.
3.마커 애너테이션의 장점
거대한 애너테이션 시스템의 지원을 받는다. 애너테이션을 적극 활용하는 프레임워크에서는 마커 애너테이션을 쓰는 쪽이 일관성을 지키기 좋다.
그럼 언제 무엇을 쓸까?
1.클래스와 인터페이스 외의 프로그램 요소(모듈,패키지,필드,지역변수 등)에 마킹해야 할 때는 애너테이션을 쓸 수 밖에 없다.
2.클래스나 인터페이스에 적용해야 할때는, 이 마킹된 객체를 매개변수로 받는 메서드를 작성할 일 이 있다면 마커 인터페이스를 써야 한다(컴파일 오류를 잡아줄 수 있기 때문에). 그렇지 않다면 애너테이션을 활용하자
'자바 메모장 > 이펙티브 자바' 카테고리의 다른 글
아이템43] 람다보다는 메서드 참조를 사용하라 (0) | 2021.08.16 |
---|---|
아이템42] 익명클래스보다는 람다를 사용하라 (0) | 2021.08.16 |
아이템 29]이왕이면 제네릭 타입으로 만들라 (0) | 2021.07.11 |
아이템 15,16] 클래스와 멤버의 접근 권한을 최소화 (0) | 2021.07.03 |
[이펙티브 자바]객체 생성과 파괴 (0) | 2021.06.20 |