Item 28 - 배열보다는 리스트를 사용하라
배열과 제네릭의 차이 1) 배열은 공변, 제네릭은 불공변이다. 배열 : Sub가 Super의 하위타입이면 배열 Sub[]는 배열 Super[]의 하위타입이다. 제네릭 : 서로 다른 T1, T2가 있을 때, List<T1>는 List<T2>의 하위타입도 상위타입도 아니다. // 배열 : 런타임에 실패한다. Object...
배열과 제네릭의 차이 1) 배열은 공변, 제네릭은 불공변이다. 배열 : Sub가 Super의 하위타입이면 배열 Sub[]는 배열 Super[]의 하위타입이다. 제네릭 : 서로 다른 T1, T2가 있을 때, List<T1>는 List<T2>의 하위타입도 상위타입도 아니다. // 배열 : 런타임에 실패한다. Object...
제네릭을 사용하면 수많은 컴파일러 경고를 볼 수 있다. (비검사 경고) ex. 비검사 형변환 경고, 비검사 메서드 호출 경고, 비검사 매개변수화 가변인수 타입 경고 등 비검사 경고 예시 Set<String> words = new HashSet(); 위 코드에서는 다음과 같은 경고를 볼 수 있다. Raw use of parame...
클래스와 인터페이스 선언에 타입 매개변수가 쓰이면, 제네릭 클래스 혹은 제네릭 인터페이스라 한다. 또 이들을 통틀어 제네릭 타입이라고 한다. 로 타입(raw type) 제네릭 타입을 하나 정의하면 그에 딸린 로 타입(raw type)도 함께 정의된다. 제네릭 타입에서 타입 매개변수를 사용하지 않을 때를 로 타입이라고 한다. ...
소스 파일 하나에 톱레벨 클래스를 여러 개 선언하더라도 자바 컴파일러는 불평하지 않는다. 하지만 아무런 득이 없을 뿐더러 심각한 위험을 감수해야 한다. 한 클래스를 여러 가지로 정의할 수 있다. 그 중 어느 것을 사용할지는 어느 소스 파일을 먼저 컴파일하냐에 따라 달라진다. 두 클래스가 한 파일...
중첩 클래스 (nested class) 중첩 클래스는 다른 클래스 안에 정의된 클래스를 말한다. 자신을 감싼 바깥 클래스에서만 쓰여야한다. 정적 멤버 클래스, (비정적) 멤버 클래스, 익명 클래스, 지역 클래스 정적 멤버 클래스 다른 클래스 내부에서 static으로 선언된 클래스 다른 정적 멤버와 똑같은 접근 규칙을 적용받는다...
태그 달린 클래스 두 가지 이상의 의미를 표현할 수 있고, 현재 표현하는 의미를 태그 값으로 알려주는 클래스 public class Figure { enum Shape { RECTANGLE, CIRCLE }; // 태그 필드 - 현재 모양을 나타낸다. final Shape shape; // 다음 필드들은 모양이 사각...
인터페이스는 자신을 구현한 클래스의 인스턴스를 참조할 수 있는 타입 역할을 하는데, 인터페이스는 이 용도로만 사용해야 한다. 상수 인터페이스는 메서드 없이 static final 필드로만 가득 찬 인터페이스로, 인터페이스를 잘못 사용한 예이다. public interface PhysicalConstants { static final do...
디폴트 메서드의 도입 자바 8 이전에는 기존 구현체를 깨뜨리지 않고는 인터페이스에 메서드를 추가할 방법이 없었다. 자바 8부터는 디폴트 메서드가 소개되면서 기존 인터페이스에 메서드를 추가할 수 있게 되었다. 그러나 이렇게 추가된 디폴트 메서드가 모든 기존 구현체들과 매끄럽게 연동되리라는 보장은 없다. 디폴트 메서드 추가 시 주의...
인터페이스의 장점 자바 8부터 인터페이스도 디폴트 메서드를 제공할 수 있다. 기존 클래스에 손쉽게 새로운 인터페이스를 구현해 넣을 수 있다. BUT, 추상 클래스는 그렇지 않다. 새로 추가된 추상 클래스의 모든 자손이 상속 구조를 가지면서 혼란을 준다. 인터페이스는 믹스인(mixin) 정의에 안...
상속을 고려한 설계와 문서화 📃 (1) 상속용 클래스는 내부 구현을 문서로 남겨야 한다. 상속용 클래스는 재정의 할 수 있는 메서드들을 내부적으로 어떻게 이용하는지 문서로 남겨야 한다. 아래와 같이 @implSpec 태그를 이용해서 불필요하게 내부 구현 방식을 설명해야 한다. (2) 클래스의 내부 동작 과정 중간에 끼어 들어갈 수 있...