본문 바로가기

자바

Effective Java ( 이펙티브 자바 ) - 아이템 30 이왕이면 제네릭 메서드로 만들라 클래스와 마찬가지로, 메서드도 제네릭으로 만들 수 있다. 매개변수화 타입을 받는 정적 유틸리티 메서드는 보통 제네릭이다. 예컨대 Collections의 '알고리즘'메서드 ( sort, binarySearch 등 )는 모두 제네릭이다. public static Set union(Set s1, Set s2) { Set result = new HashSet(s1); result.addAll(s2); return result; } 컴파일은 되지만 경고가 두 개 발생한다. Set result = new HashSet(s1); result.addAll(s2); 경고를 없애려면 이 메서드를 타입 안전하게 만들어야 한다. 메서드 선언에서의 세 집합(입력 2개, 반환 1개)의 원소 타입을.. 더보기
Effective Java ( 이펙티브 자바 ) - 아이템 29 이왕이면 제네릭 타입으로 만들라 제네릭 타입을 새로 만드는 일은 조금 더 어렵다. 그래도 배워두면 그만한 값어치는 충분히 한다. public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Object e) { ensureCapacity(); elements[size++] = e; } poublic Object pop() { if (size == 0) throw new EmptyStackExc.. 더보기
Effective Java ( 이펙티브 자바 ) - 아이템 28 배열보다는 리스트를 사용하라 배열과 제네릭 타입에는 중요한 차이가 두 가지 있다. 첫 번째, 배열은 공변(covariant)이다. 어려워 보이는 단어지만 뜻은 간단하다. Sub가 Super의 하위 타입이라면 배열 Sub[]는 배열 Super[]의 하위 타입이 된다(공변, 즉 함께 변한다는 뜻이다). 반면, 제네릭은 불공변이다. 즉, 서로 다른 타입 Type1과 Type2가 있을 때, List은 List의 하위 타입도 아니고, 상위 타입도 아니다. 이것만 보면 제네릭에 문제가 있다고 생각할 수도 있지만, 사실 문제가 있는 건 배열 쪽이다. 다음은 문법상 허용되는 코드다. Object[] objectArray = new Long[1]; objectArray[0] = "타입이 달라 넣을 수 없다."; // A.. 더보기
Effective Java ( 이펙티브 자바 ) - 아이템 27 비검사 경고를 제거하라 제네릭을 사용하기 시작하면 수많은 컴파일러 경고를 보게 될 것이다. 대부분의 비검사 경고는 쉽게 제거할 수 있다. Set exaltation = new HashSet(); 그러면 컴파일러는 무엇이 잘못됐는지 친절히 설명해줄 것이다(javac 명령줄 인수에 -Xlint:uncheck 옵션을 추가해야 한다). 사실 컴파일러가 알려준 타입 매개변수를 명시하지 않고, 자바 7부터 지원하는 다이아몬드 연산자()만으로 해결할 수 있다. 그러면 컴파일러가 올바른 실제 타입 매개변수를 추론해준다. Set exaltation = new HashSet(); 제거하기 훨씬 어려운 경고도 있다. 곧바로 해결되지 않는 경고가 나타나도 포기하지 말자! 할 수 있는 한 모든 비검사 경고를 제거하라. 즉, 런.. 더보기
Effective Java ( 이펙티브 자바 ) - 5장 제네릭 아이템 26 제네릭 제네릭은 자바 5부터 사용할 수 있다. 제네릭을 지원하기 전에는 컬렉션에서 객체를 꺼낼 때마다 형변환을 해야 했다. 실수로 엉뚱한 타입의 객체를 넣어두면 런타임에 형변환 오류가 나곤 했다. 반면, 제네릭을 사용하면 컬렉션이 담을 수 있는 타입을 컴파일러에 알려주게 된다. 그래서 컴파일러는 알아서 형변환 코드를 추가할 수 있게 되고, 안전하고 명확한 프로그램을 만들어 준다. 하지만, 코드가 복잡해진다는 단점이 따라온다. 이번 장에서는 제네릭의 이점을 최대로 살리고 단점을 최소하하는 방법을 이야기한다. 로 타입은 사용하지 말라 용어부터 정리하고 가자. 클래스와 인터페이스 선언에 타입 매개변수가 쓰이면, 이를 제네릭 클래스 혹은 제네릭 인터페이스라 한다. 제네릭 클래스와 제네릭 인터페이스를 통틀어 제네.. 더보기
Effective Java ( 이펙티브 자바 ) - 아이템 25 톱레벨 클래스는 한 파일에 하나만 담으라 소스 파일 하나에 톱레벨 클래스를 여러 개 선언하더라도 자바 컴파일러는 불평하지 않는다. 하지만 아무런 득이 없을 뿐더러 심각한 위험을 감수해야 하는 행위다. 이렇게 하면 한 클래스를 여러 가지로 정의할 수 있으며, 그중 어느 것을 사용할지는 어느 소스 파일을 먼저 컴파일하냐에 따라 달라지기 때문이다. public class Main { public static void main(String[] args) { System.out.println(Utensil.NAME + Dessert.NAME); } } 파일명 - Utensil.java 가 정의되어있다. class Utensil { static final String NAME = "pan"; } class Dese.. 더보기
Effective Java ( 이펙티브 자바 ) - 아이템 24 멤버 클래스는 되도록 static으로 만들라 중첩 클래스란 다른 클래스 안에 정의된 클래스를 말한다. 중첩 클래스는 자신을 감싼 바깥 클래스에서만 쓰여야 하며, 그 외의 쓰임새가 있다면 톱레벨 클래스로 만들어야 한다. 중첩 클래스의 종류는 정적 멤버 클래스, (비정적) 멤버 클래스, 익명 클래스, 지역 클래스, 이렇게 네 가지다. 이 중 첫번째를 제외한 나머지는 내부 클래스(inner class)에 해당한다. 이번 아이템에서는 각각의 중첩 클래스를 언제 그리고 왜 사용해야 하는지 이야기한다. 먼저 가장 간단한 정적 멤버 클래스를 알아보자. 정적 멤버 클래스는 다른 클래스 안에 선언되고, 바깥 클래스의 private 멤버에도 접근할 수 있다는 점만 제외하고는 일반 클래스와 똑같다. 정적 멤버 클래스는 다른.. 더보기
1급 객체(First-class citizen) 란? 요즘, 함수형 프로그래밍이 떠오르면서 1급 객체(First-class citizen)란 말을 많이 듣게 되는 것 같다. 1급 객체의 특징은 아래와 같다. 아래 3 가지조건을 충족한다면 1급 객체라고 할수 있다. 1급 객체의 조건 3가지 변수나 데이타에 할당 할 수 있어야 한다. 객체의 인자로 넘길 수 있어야 한다. 객체의 리턴값으로 리턴 할수 있어야 한다. 주로 사용하고 있는 언어인 JAVA에서는, 함수가 1급 객체에 해당하지 않는다. Kotlin, JavaScript 등의 언어에서는 변수에 함수를 할당하고 사용할 수 있다. 하지만, JAVA는 불가능하다. 그렇지만, JAVA의 Lambda는 그렇다면 어떻게 되는것인가?라는 질문을 던질 수 있다. 이는 메서드가 1개만 존재하는 인터페이스/클래스를 통해, .. 더보기