아이템 9 - try-finally 보다는 try-with-resources 를 사용하라
- 자바 라이브러리 중에는 자원을 사용 후 close 메소드를 통해 직접 닫아주어야 하는 자원들이 있음.
(ex InputStream, OutputStream...)
- 과거엔 try-finally가 주로 쓰임.
- 그러나 try-finally는 자원이 두개 이상 같이 쓰일 경우 코드가 지져분해지기 쉬우며, 물리적 문제 발생시 혹은 try 문 내에 쓰인 자원 메소드 내에서 예외가 발생하여 바로 return 되는 경우 예외 확인이 안될 수 있으며, finally 문에서 예외 발생시에도 예외 상황 확인이 어려울 수 있음.
-> try-with-resources 문으로 해결 가능!
try (InputStream in = new FileInputStream(src)) {
자원 읽기 소스들...
}
- 단, try 중괄호 안에 들어갈 수 있는 건 AutoCloseable 인터페이스를 구현한 자원이어야 함.
아이템 10 - equals는 일반 규약을 지켜 재정의하라
- equals는 객체간 비교에서도 사용하는데, 이 때에 재정의 해서 사용해야 한다는 것이다.
- 이 때에 지켜야 하는 것이 일반규약이다.
- 반사성 : 객체는 자기 자신과 같아야 한다.
- 대칭성 : 두 객체는 서로에 대한 동치 여부에 똑같이 답해야 한다.
ex>
CaseInsensitiveStrings ciss = new CaseInsensitiveStrings("France");
String str = "France";
이런 예제가 있을때(책 참조), (ciss 객체가 equals를 재정의 하여 String과 비교를 할 수 있게 해두었을 때)
ciss.equals(str) //true
str.equals(ciss) //false String 객체는 CaseInsensitiveStrings 객체를 모르기 때문
이런식으로 한쪽으로만 equals가 나오면 안된다는 의미.
- 추이성 : x=y, y=z 이면, x=y=z가 되어야 한다는 의미.
-> 이 추이성을 깨뜨리는게 상속이다. 상속을 사용하게 되면, 이 추이성을 제대로 지키지 못하게 되어 equals를 재정의하여 사용하게는 게 문제가 될 수 있다. 책 60p에서 상속 대신 private로 필드를 선언하고 뷰를 반환하는 방법을 소개하고 있는데 이 방법을 통하면 equals 사용이 용이하다. (꼭 다시 읽어볼 것)
(ps. 상위 클래스가 직접 인스턴스 생성이 불가한 추상 클래스라면, 추이성을 깨뜨리지 않고도 상속을 사용 하고, equals 규약을 지킬 수 있다고 한다.)
- 일관성 : 두 객체가 같다면, 앞으로도 영원이 같아야 한다.
equals의 판단에 신뢰할 수 없는 자원이 끼어들게 해서는 안된다.
(ex> URL equals는 네트워크를 통함에 따라 달라질 수 있다? -> 이는 실수였으니 따라하면 안된다고 한다.)
- null-아님 : 객체가 null이 아니어야 한다는 의미.
그러나 equals에서 null체크를 할 필요는 없고 instanceOf에 의해 어차피 null은 걸러지게 됨(false)
ETC.. : float과 double형을 제외한 기본 타입 필드는 '=='연산자를 통해 비교하고 참조 타입 필드는 각각의 equals 메소드로 비교한다. (float과 double형은 Float.compare(float f1, float f2) 와 Double.compare(double d1, double d2)로 비교한다.) -> 특수한 부동소수값을 다뤄야 하기 때문..
- 중요한 포인트 세가지 : equals를 구현했다면, 대칭적인지? 추이성이 있는지? 일관적인지? 세가지만 테스트 해봐도 거의 맞다고 한다. 반사성과 null-아님도 만족해야 하지만, 이 두개가 문제되는 경우는 거의 없다고 한다.
- 구글의 AutoValue를 사용하거나, IDE의 자동완성을 사용하면 이와 같은 고민은 필요 없을 수도 있다. 단, IDE의 자동완성 사용의 경우 테스트 코드를 꼭 작성해두자-!! 하위 클래스가 추가되거나 하는 등의 변경시 equals를 다시 재정의해야 하는 것을 IDE가 알려주지는 않으니까-!!
아이템 11 - equals를 재정의 하려거든 hashcode도 재정의하라
- 앞서 공부한 equals가 두 객체를 같다고 판단하면, 두 객체의 hashcode도 같은 값을 반환해야 한다.
-> hashmap 같은 곳에 객체를 넣었다가 get을 할 때 hashcode 값으로 같은 객체값을 꺼낼지 구분하는데, equals로는 같다고 판단한 객체라도 hashcode를 동일하게 리턴하도록 재정의하지 않았다면, 찾을 수 없다.
- hashcode값을 작성하는 방법이 나와있고, hashcode를 작성하는 방법을 자세히 공표하지 않는게 추후 릴리즈 버전에서 수정하거나 클라이언트쪽에서 재정의해서 사용할 수 있게끔 하는 장점이 있다고 소개한다. 더불어 hashcode도 AutoValue나 IDE로 재정의 하는게 편하다.
아이템12 - toString을 항상 재정의하라
- toString의 규약은 "모든 하위 클래스에서 이 메서드를 재정의하라" 고 한다.
- toString 메서드는 객체를 println, printf, 문자열 연결 연산자(+), assert 구문에 넘길 때, 디버거가 객체를 출력할 때 자동으로 불린다. (로그 같은 것에서 해당 객체의 오류 메시지를 로깅할 때 이를 재정의 해두지 않았다면 불필요한 문자열만 나올 것이다.) -> 따라서 뭔가 유용한 값이 나오도록 정의해두는 것이 좋다.
[책에서는 그 객체가 가진 주요 정보 모두를 반환하는 것이 좋다] 고 한다.
- 정적 유틸리티 클래스는 toString을 제공할 이유가 없다.
- 대부분의 열거 타입도 자바가 이미 완벽한 toString을 제공하니 따로 재정의하지 않아도 된다.
- but, 하위 클래스들이 공유해야 할 문자열 표현이 있는 추상 클래스라면 toString을 재정의해줘야 한다.
'책(독서)' 카테고리의 다른 글
[이펙티브자바] ~135p item 17~20 (0) | 2020.10.13 |
---|---|
[이펙티브자바] ~104p item 13~16 (0) | 2020.10.12 |
[이펙티브자바] ~46p 아이템 5~8 (0) | 2020.10.08 |
[이펙티브자바] ~27p item1~4 (0) | 2020.10.05 |
[켄트벡의 구현패턴] ~마지막 (부록 성능측정) (0) | 2020.09.21 |