Item27. 비검사 경고를 제거하라
@SuppressWarnings
compiler 경고를 제거할수는 없지만 타입 안전하다고 확신할 수 있다면 @SuppressWarning(“unchecked”) annotation을 달아 경고를 숨길 수 있다, 단 rumtime에 ClassCastException이 발생하지 않도록 타입 안전함을 검증해야 한다.
compiler 경고를 제거할수는 없지만 타입 안전하다고 확신할 수 있다면 @SuppressWarning(“unchecked”) annotation을 달아 경고를 숨길 수 있다, 단 rumtime에 ClassCastException이 발생하지 않도록 타입 안전함을 검증해야 한다.
클래스와 인터페이스 선언에 타입 매개변수(type parameter)가 쓰이면 이를 generic class 또는 generic interface라 한다. 이 두 개를 통칭해서 Generic type이라고 부른다.
1 | public class GenericExample<T>{} // T : 타입 매개변수 |
각각의 generic type은 매개변수화 타입 (parameterized type)을 정의한다. 매개변수화타입은 <> 괄호 안에 실제 타입을 명시함으로서 정의가 가능하다.
1 | GenericExample<String> stringGenericExample = new GenericExample<>(); |
raw tye은 generic type을 하나 정의하면 함께 정의되는데, generic type에서 타입 매개변수를 전혀 사용하지 않았을떄를 말한다. , raw type이 generic type을 하나 정의할떄마다 같이 생성되는 이유는 기존 java code와 호환성 문제떄문이다.
1 | GenericExample rawTypeGeneric = new GenericExample(); |
소스 파일 하나당 top-level class를 여러개 선언해도 compile error는 나지 않는다,
1 | // Utensil.java |
1 | class Dessert { |
위와 같이 하나의 java file에 여러개의 class가 들어있는 경우 문제가 생길수도 있다.
중첩 class (nested class) 란 다른 class 안에 정의된 class를 말한다. 중첩 class는 자신을 감싼 바깥 class에서만 쓰여야 한다.
정적 멤버 class
멤버 class
지역 class
익명 class
헌재 표현하는 의미를 태그 값으로 알려주는 class 는 아래와 같이 class 계층구조를 사용하지 않고, 한 class내에 태그 필드를 가지는 class를 말한다.
1 | public class Figure { |
태그 필드를 가지고, 분기처리 (swith,if-else)를 하기 때문에 코드 가독성이 떨어지고, 계층형 구조로 가져갔을때 불필요한 코드들이 생긴다.
태그 값마다 필요한 필드가 다른데, 이를 모두 하나의 class에 보관함으로, 객체를 생성하였을떄 사용되지 않는 필드 (메모리 낭비) 도 같이 초기화 된다.
변경에 열려있다, 태그 값 추가시마다 분기로직을 수정해야 한다.
인스턴스 타입을 보고 현재 타입이 나타내는 의미를 알 수가 없다.
인터페이스는 자신을 구현한 class의 instance를 참조할 수 있는 타입 역할을 한다.
즉 class가 어떤 인터페이스를 구현한다는 것은 자신의 인터페이스로 무엇을 할수 있을 지 client에게 얘기해주는 것이며, 인터페이스는 오직 이 용도로만 사용해야 한다.
java 8 이후부터는 interface에 default method를 추가할 수 있게 되었다.
default method 를 기존 인터페이스에 추가하였을떄 다음과 같은 사이드 이펙트가 발생할 수 있으니, 고려해서 추가하자는 내용이다.
추상 class와 인터페이스의 가장 큰 차이점은 추상 class가 정의한 type을 구현하는 class는 반드시 추상 class의 하위 타입이 되야한다는 점이다.
java는 단일 상속만 지원함으로, 추상 class 방식은 새로운 타입을 정의하는데 제약을 갖게 된다. 반면 인터페이스의 경우는 어떤 class를 상속했더라도 같은 type으로 취급된다
기존 class에 새로운 인터페이스를 구현해넣는것은 쉬우나, 새로운 추상 class를 넣기는 힘들다.
두 class가 동일한 추상 class 를 확장하려면 그 추상 class는 계층구조상 두 class의 공통조상이여야 한다.
문서화 예시 : https://docs.oracle.com/javase/7/docs/api/java/util/AbstractCollection.html
API 문서의 method설명 끝에서 종종 ‘This Implementation’ ~ 로 시작하는 절을 볼 수 있는데 이 부분이 method의 내부 동작 방식을 설명하는 곳이다.
클래스를 안전하게 상속할 수 있도록 하려면, 내부 구현 방식에 대해 설명해주어야 한다.
( Java method 주석에 @implSpec tag를 붙여주면 자바독 도구가 생성해준다. )
상위 class 내부 구현 변경에 따라 하위 class가 영향을 받을 수도 있다. 상위 class가 확장을 충분히 고려해두고 설계되지 않으면 하위 class는 상위 class의 변화맞추어 수정되야 한다.