Java

    이펙티브 자바, 쉽게 정리하기 - item 32. 제네릭과 가변인수를 함께 쓸 때는 신중하라

    이펙티브 자바, 쉽게 정리하기 - item 32. 제네릭과 가변인수를 함께 쓸 때는 신중하라 가변인수 메서드의 허점 가변인수 메서드를 호출하면 가변인수를 담기 위한 배열이 자동으로 하나 만들어진다. 이 배열은 내부로 감춰져야 하는데, 클라이언트에 공개되면서 문제가 발생할 수 있다. 특히 varargs 변수에 제네릭이나 매개변수화 타입이 포함되면 알기 어려운 컴파일 경고가 발생한다. 실체화 불가 타입(제네릭)을 가변인수로 이용했을 때 @Test public void unableToReifyTest() { Assertions.assertThrows(ClassCastException.class, () -> { reifyExampleMethod(List.of("안","녕","하")); }); } public s..

    이펙티브 자바, 쉽게 정리하기 - item 31. 한정적 와일드카드를 사용해 API 유연성을 높이라

    이펙티브 자바, 쉽게 정리하기 - item 31. 한정적 와일드카드를 사용해 API 유연성을 높이라 와일드 카드 타입을 사용해야 하는 이유 제네릭은 불공변이다. 하위 혹은 상위 타입을 기본적으로는 포용하지 않게 되어있다. 필요하다면, extends 혹은 super를 이용하면 된다. static class StackWithGeneric { private E[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public StackWithGeneric() { elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(E e) {..

    이펙티브 자바, 쉽게 정리하기 - item 30. 이왕이면 제네릭 메서드로 만들라

    이펙티브 자바, 쉽게 정리하기 - item 30. 이왕이면 제네릭 메서드로 만들라 제네릭 메서드 작성법 public static Set union(Set s1, Set s2) { Set result = new HashSet(s1); result.addAll(s2); return result; } 순서대로 타입 매개변수 목록, 반환 타입, 파라미터 타입 3가지를 메서드 시그니처에 입력할 수 있다. 활용 예시 @Test public void unionTest() { Set guys = Set.of("톰", "딕", "헤리"); Set stooges = Set.of("래리", "모에", "컬리"); Set aflCio = union(guys, stooges); System.out.println("aflCio ..

    이펙티브 자바, 쉽게 정리하기 - item 29. 이왕이면 제네릭 타입으로 만들라

    이펙티브 자바, 쉽게 정리하기 - item 29. 이왕이면 제네릭 타입으로 만들라 제네릭 타입으로 스택 구현하기 Before Generic static class StackWithArray { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public StackWithArray() { elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Object e) { ensureCapacity(); elements[size++] = e; } public Object pop() { if (size == 0) ..

    이펙티브 자바, 쉽게 정리하기 - item 28. 배열보다는 리스트를 사용하라

    이펙티브 자바, 쉽게 정리하기 - item 28. 배열보다는 리스트를 사용하라 공변(covariant)과 불공변(invariant) 개념 공변: 함께 변한다. 배열은 공변이 적용된다. 불공변: 함께 변하지 않는다. (공변이 아니다.) 리스트는 불공변이 적용된다. 공변(covariant) 불공변(invariant) 예제 테스트 코드 @Test public void covariantTest() { Object[] objects = new Long[1]; objects[0] = "String"; // ArrayStoreException } Object[]의 공변 특성을 이용하여 objects를 선언 후에 Long[] 저장소를 만들어 할당했다. 해당 저장소 타입이 Object[]로 정의되어 있어 클라이언트는 아..

    이펙티브 자바, 쉽게 정리하기 - item 27. 비검사 경고를 제거하라

    이펙티브 자바, 쉽게 정리하기 - item 27. 비검사 경고를 제거하라 비검사 경고가 나타나는 경우 Set exaltation = new HashSet(); 위는 비검사 경고가 발생하는 코드의 예이다. 위의 경우엔 앞에서 나왔던 로 타입을 사용해서 발생했다. Venery.java:4: warning: [unchecked] unchecked conversion Set exaltation = new HashSet(); required: Set found: HashSet 자바 7부터는 다이아몬드 연산자를 뒤에 적어주면 자동으로 타입 추론을 해준다. 할 수 있는 한 위와 같은 비검사 경고를 모두 제거해주어야 한다. 그래야 타입 안정성이 보장되고, 런타임에 ClassCastException이 뜰 확률이 줄어든다..

    이펙티브 자바, 쉽게 정리하기 - item 26. 로 타입은 사용하지 말라

    이펙티브 자바, 쉽게 정리하기 - item 26. 로 타입은 사용하지 말라 용어 정리 클래스 혹은 인터페이스 선언에 타입 매개변수가 쓰이면 이를 제네릭 클래스(generic class) 혹은 제네릭 인터페이스(generic interface)라 한다. 이를 통틀어 제네릭 타입(generic type)이라고 한다. 각각의 제네릭 타입은 일련의 매개변수화 타입(parameterized type)을 정의한다. 제네릭 타입을 정의하면 그에 딸린 로 타입(raw type)도 함께 정의된다. 로 타입이란 제네릭 타입에서 타입 매개변수를 전혀 사용하지 않을 때를 말한다. ex) List, Set 로 타입은 타입 선언에서 제네릭 타입 정보가 전부 지워진 것처럼 동작한다. 제네릭이 도래하기 전 코드와 호환되도록 하기 위..

    이펙티브 자바, 쉽게 정리하기 - item 25. 톱 레벨 클래스는 한 파일에 하나만 담으라

    이펙티브 자바, 쉽게 정리하기 - item 25. 톱 레벨 클래스는 한 파일에 하나만 담으라 두 클래스가 한 파일에 정의되어 있을 때 Utensil.java class Utensil { static final String NAME = "pan"; } class Dessert { static final String NAME = "cake"; } Dessert.java class Utensil { static final String NAME = "pot"; } class Dessert { static final String NAME = "pie"; } Main.java public class Main { public static void main(String[] args) { System.out.printl..

    이펙티브 자바, 쉽게 정리하기 - item 24. 멤버 클래스는 되도록 static으로 만들라

    이펙티브 자바, 쉽게 정리하기 - item 24. 멤버 클래스는 되도록 static으로 만들라 중첩 클래스란? 중첩 클래스(nested class)란, 다른 클래스 안에 정의된 클래스를 말한다. 오직 자신을 감싼 바깥 클래스에서만 쓰일 용도로 만들어진 클래스이다. 그 외의 용도로 쓰일 클래스는 톱레벨 클래스로 만들어야 한다. 중첩 클래스의 종류? 정적 멤버 클래스 비정적 멤버 클래스 익명 클래스 지역 클래스 정적 멤버 클래스를 제외한 나머지는 내부 클래스(inner class)에 해당한다. 정적 멤버 클래스는 다른 클래스 안에 선언되어 바깥 클래스의 private 멤버에도 접근 가능한 특성이 있다. 흔히 바깥 클래스와 함께 쓰일 때만 유용한 public 도우미 클래스로 쓰인다. 정적 멤버 클래스와 다른 ..

    이펙티브 자바, 쉽게 정리하기 - item 23. 태그 달린 클래스보다는 계층구조를 활용하라

    이펙티브 자바, 쉽게 정리하기 - item 23. 태그 달린 클래스보다는 계층구조를 활용하라 태그달린 클래스의 예 public class Item23Test { static class Figure { enum Shape { RECTANGLE, CIRCLE }; // 태그 필드 - 현재 모양을 나타낸다. final Shape shape; // 다음 필드들은 모양이 사각형(RECTANGLE)일 때만 쓰인다. double length; double width; // 다음 필드는 모양이 원(CIRCLE)일 때만 쓰인다. double radius; // 원용 생성자 Figure(double radius) { shape = Shape.CIRCLE; this.radius = radius; } // 사각형용 생성자 F..

    이펙티브 자바, 쉽게 정리하기 - item 22. 인터페이스는 타입을 정의하는 용도로만 사용하라

    이펙티브 자바, 쉽게 정리하기 - item 22. 인터페이스는 타입을 정의하는 용도로만 사용하라 안티패턴: 상수 인터페이스 public interface PhysicalConstants { // 인터페이스 내부의 필드는 `static final`이 자동으로 붙는다. // 아보가드로 수 (1/몰) double AVOGADROS_NUMBER = 6.022_140_857e23; // 볼츠만 상수 (J/K) double BOLTZMANN_CONSTANT = 1.380_648_52e-23; // 전자 질량 (kg) double ELECTRON_MASS = 9.109_383_56e-31; } @Test public void test() { System.out.println(PhysicalConstants.AVOGA..

    이펙티브 자바, 쉽게 정리하기 - item 21. 인터페이스는 구현하는 쪽을 생각해 설계하라

    이펙티브 자바, 쉽게 정리하기 - item 21. 인터페이스는 구현하는 쪽을 생각해 설계하라 인터페이스의 수정과 디폴트 메서드 자바8 이전에는 인터페이스는 한번 정의되면 절대 새로운 메서드가 추가되거나 기존 메서드가 사라지지 않는다는 전제 하에 코드를 작성했다. 자바8 에서 디폴트 메서드가 등장하며 새로운 메서드를 추가할 수 있게 되었다. 주로 람다를 활용하기 위해서이다. 하지만 위험이 사라진 것은 아니다. 생각할 수 있는 모든 상황에서 불변식을 해치지 않는 디폴트 메서드를 작성하는 것은 쉽지 않다. 디폴트 메서드를 선언하면, 디폴트 메서드를 재정의하지 않은 모든 클래스에서 디폴트 구현이 쓰이게 된다. removeIf 메서드로 보는 인터페이스 디폴트 메서드의 예 default boolean removeI..

반응형