Java 13

Effective Java Item54. null이 아닌, 빈 컬렉션이나 배열을 반환하라.

null이 아닌, 빈 배열이나 컬렉션을 반환하라. null을 반환하는 API는 사용하기 어렵고 오료 처리 코드도 늘어난다. 그렇다고 성능이 좋은 것도 아니다.컬렉션을 반환할 때 빈 컨테이너를 할당하는 데도 비용이 드니 null을 반환하는 쪽이 낫다는 주장이 있다. 하지만 두 가지 면에서 틀린 주장이다.성능 분석 결과 이 할당이 성능 저하의 주범이라고 확인되지 않는 한 이 정도의 성능 차이는 신경 쓸 수준이 못 된다. (item 67)빈 컬렉션과 배열은 굳이 새로 할당하지 않고도 반환할 수 있다.ex) 빈 컬렉션을 반환하는 올바른 예public List getCheeses() { return new ArrayList(cheesesInStock);}사용 패턴에 따라 빈 컬렉션 할당이 성능을 눈에 띄게 떨어..

Java/EffectiveJava 2025.02.22

Effective Java Item53. 가변인수는 신중히 사용하라.

인수 개수가 일정하지 않은 메서드를 정의해야 한다면 가변인수가 반드시 필요하다. 메서드를 정의할 때 필수 매개변수는 가변인수 앞에 두고, 가변인수를 사용할 때는 성능 문제까지 고려하자.가변인수 메서드를 호출하면, 가장 먼저 인수의 개수와 길이가 같은 배열을 만들고 인수들을 이 배열에 저장하여 가변인수 메서드에 건네준다.ex) 간단한 가변인수 활용 예static int sum(int... args) { int sum = 0; for (int arg : args) { sum += arg; } return sum;}ex) 인수가 1개 이상이어 하는 가변인수 메서드 - 잘못 구현한 예static int min(int... args) { if (args.length == 0..

Java/EffectiveJava 2025.02.22

Effective Java Item42. 익명 클래스보다는 람다를 사용하라.

익명 클래스Collections.sort(words, new Comparator() { public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()) }});람다Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(), s2.length()));람다는 함수나 익명 클래스와 개념은 비슷하지만 코드는 훨씬 간결하다. 람다를 사용할 때는 타입을 명시해야하는 코드가 더 명확할 때만 제외하고는, 람다의 모든 매개변수 타입은 생략하자.람다 자리에 비교자 생성 메서드를 사용하면 코드를 더 간결하게 만들 수 있다.Collection..

Java/EffectiveJava 2025.02.16

Effective Java Item41. 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라.

마커 인터페이스(marker interface)? 아무 메서드도 담고 있지 않고, 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해주는 인터페이스 ex) Serializable Serializable은 자신을 구현한 클래스의 인스턴스는 ObjectOutputStream을 통해 쓸 수 있다고, 즉 직렬화 할 수 있다고 알려준다.마커 인터페이스는 구현한 클래스의 인스턴스들을 구분하는 타입으로 쓸 수 있다.자바의 직렬화는 Serializable 마커 인터페이스를 보고 그 대상이 직렬화할 수 있는 타입인지 확인한다.마커 인터페이스는 객체의 특정 부분을 불변식으로 규정하거나, 그 타입의 인스턴스는 다른 클래스의 특정 메서드가 처리할 수 있다는 사실을 명시하는 용도로 사용할 수 있다.즉, 타입을 정의할 거라..

Java/EffectiveJava 2025.02.16

Effective Java Item33. 타입 안전 이종 컨테이너를 고려하라.

제네릭은 Set, Map 등의 컬렉션과 ThreadLocal, AtomicReference 등의 단일 원소 컨테이너에 흔히 쓰인다. (Set는 하나의 타입 매개변수만 있으면 되며, Map에는 키와 값의 타입을 뜻하는 2개만 필요하다.)더 유연하게 타입 매개변수를 사용할 수 있는 방법은 무엇일까? 여기서 나온 방법이 바로 타입 안전 이종 컨테이너 패턴(type safe heterogeneous container pattern)이다. 타입 안전 이종 컨테이너 패턴? 컨테이너 대신 키를 매개변수화한 다음, 컨테이너에 값을 넣거나 뺄 때 매겨변수화한 키를 함께 제공한다.예시.public static void main(String[] args) { Favorite f = new Favorite(); ..

Java/EffectiveJava 2025.02.09

Effective Java Item32. 제네릭과 가변인수를 함께 쓸 때는 신중하라.

가변인수(varargs) 메서드와 제네릭은 자바 5때 함께 추가되었으나, 둘의 조합은 잘 어울리지 않는다.가변인수는 메서드에 넘기는 인수의 개수를 클라이언트가 조절할 수 있게 해주는데, 구현 방식에 허점이 있다. 그 허점이란, 가변인수 메서드를 호출하면 가변인수를 담기 위한 배열이 하나 만들어지는데, 그 배열을 내부에 감추지 않고 클라이언트에게 노출하는 문제가 생기게 되면서 제네릭이나 매개변수화 타입이 포함되면 알기 어려운 컴파일 경고가 발생한다.// possible heap pollution from parameterized vararg type static void dangerous(List... stringLists) { List intList = List.of(42); Objec..

Java/EffectiveJava 2025.02.09

Effective Java Item26. 로 타입은 사용하지 말라.

제네릭이란? 제네릭 클래스 or 제네릭 인터페이스 : 클래스와 인터페이스 선언에 타입 매개변수가 쓰인 것제네릭 타입 : 제네릭 클래스와 제네릭 인터페이스를 통틀어 정의List제네릭 타입의 구성 List : 로 타입(raw type)로 타입은 타입 선언에서 제네릭 타입 정보가 전부 지워진 것처럼 동작한다.E : 매개변수화 타입(parameterized type)List 인 경우 정규 타입 매개변수 E에 해당하는 실제 타입 매개변수이다.주제로 넘어가 로 타입을 사용하지 말라는 것은 무엇?이러한 제네릭에 대해 매개변수화 타입을 생략하여 사용하는 경우가 있는데, 이를 로 타입으로만 사용하는 것이다. ex) List, Collection 으로만 사용로 타입으로만 사용하면 제네릭이 안겨주는 안정성과 표현력을 모두..

Java/EffectiveJava 2025.01.24

Effective Java Item24. 멤버 클래스는 되도록 static으로 만들라.

https://www.infoworld.com/article/2255920/avoid-memory-leaks-in-inner-classes.html중첩 클래스(nested class)?다른 클래스 안에 정의된 클래스를 말한다.자신을 감싼 바깥 클래스에서만 쓰여야 하며, 그 외의 쓰임새가 있다면 톱레벨 클래스로 만들어야 한다.public class EnclosingClass { // 바깥 클래스 public class EnclosedClass // 중첩 클래스}중첩 클래스의 종류 정적 멤버 클래스(비정적)멤버 클래스익명 클래스지역 클래스정적 멤버 클래스?클래스에 static을 붙인다.다른 클래스 안에 선언되고, 바깥 클래스의 private 멤버에도 접근할 수 있다는 점만 제외하고 일반 클래스와 같다...

Java/EffectiveJava 2025.01.23

Effective Java Item20. 추상 클래스보다는 인터페이스를 우선하라.

자바가 제공하는 다중 구현 메카니즘인터페이스(Interface) : 인터페이스가 선언한 메서드를 모두 정의하고 그 일반 규악을 잘 지킨 클래스라면 다른 어떤 클래스를 상속했든 같은 타입으로 취급된다.추상 클래스(abstract class) : 추상 클래스가 정의한 타입을 구현하는 클래스는 반드시 추상 클래스의 하위 클래스가 되어야한다. 자바는 단일 상속만 지원한다. 인터페이스를 사용하면 얻을 수 있는 것기존 클래스에도 손쉽게 새로운 인페이스를 구현해넣을 수 있다.인터페이스는 믹스인 정의에 안성맞춤이다.인터페이스로는 계층구조가 없는 타입 프로엠워크를 만들 수 있다.래퍼 클래스 관용구(아이템18)와 함께 사용하면 인터페이스 기능을 향상시키는 강력한 수단이 된다.인터페이스와 추상 클래스를 적절히 사용하여 구현..

Java/EffectiveJava 2025.01.18

Effective Java Item18. 상속보다는 컴포지션을 사용하라.

상속은 코드를 재사용하는 강력한 수단이다. 하지만 잘못 사용하면 오류를 내기 쉬운 소프트웨어를 만들게 한다.메서드 상속과 달리 상속은 캡슐화를 깨트린다. - 상위 클래스가 어떻게 구현되느냐에 따라 하위 클래스의 동작에 이상이 생길 수 있다. - 상위 클래스는 릴리스마다 내부 구현이 달라질 수 있으며, 그 여파로 코드 한 줄 건드리지 않은 하위 클래스가 오동작할 수 있다.상속의 단점을 피하기 위해 새로운 메서드를 통해 재정의하는 것은 상위 클래스의 메서드가 요구하는 규약을 만족하지 못할 가능성이 크다.위 문제점을 해결하기 위해서는 새로운 클래스를 만들고 private 필드로 기존 클래스의 인스턴스를 참조하게 하는 컴포지션(composition)을 사용하자.컴포지션을 사용하면, 기존 클래스의 내부 구현 방식..

Java/EffectiveJava 2025.01.15