티스토리

GARONGURI
검색하기

블로그 홈

GARONGURI

garonguri.tistory.com/m

Garonguri 님의 블로그입니다.

구독자
2
방명록 방문하기
728x90

주요 글 목록

  • Effective Java 보호되어 있는 글입니다. 공감수 13 댓글수 7 2022. 9. 15.
  • item 90. 직렬화된 인스턴스 대신 직렬화 프록시 사용을 검토하라 Serializable은 물론 편리하다. 그러나 버그와 보안 문제가 일어날 가능성이 커질 수 밖에 없다. 이럴 때 '직렬화 프록시 패턴' 을 사용하자. 직렬화 프록시는 readObject 의 방어적 복사보다 강력하다. [ 직렬화 프록시 패턴을 사용하는 방법 ] 바깥 클래스의 논리적 상태를 정밀히 표현하는 중첩 클래스를 설계하고, private static 으로 선언하기 위 '중첩 클래스'가 바로 바깥 클래스의 직렬화 프록시다. 중첩 클래스의 생성자는 단 하나여야 하며, 바깥 클래스를 매개변수로 받는다. 중첩 클래스의 생성자는 인수로 넘어온 인스턴스 데이터를 복사한다. 일관성 검사나 방어적 복사는 필요하지 않다. 직렬화 프록시의 기본 직렬화 형태는 바깥 클래스의 직렬화 형태로 쓰기에 이상적이다. 바깥 클래.. 공감수 0 댓글수 0 2022. 9. 15.
  • item 89. 인스턴스 수를 통제해야 한다면 readResolve보다는 열거 타입을 사용하라 item3의 싱글턴 패턴을 보자! 클래스는 바깥에서 생성자를 호출하지 못하게 막는 방식으로 인스턴스가 오직 하나만 만들어짐을 보장한다. public class Elvis { public static final Elvis INSTANCE = new Elvis(); private Elvis() { ... } public void leavingTheBuilding() {...} } 여기서 class 선언부에 implements Serializable을 추가하는 순간 이 클래스는 무슨 짓을 해도 싱글턴이 아니다. 어떤 readObject를 사용하든, 이 클래스가 초기화될 때 만들어진 인스턴스와는 별개인 인스턴스를 반환하게 된다. 이 때 readResolve 기능을 이용하면 readObject가 만들어낸 인스턴스.. 공감수 0 댓글수 0 2022. 9. 15.
  • item 88. readObject 메서드는 방어적으로 작성하라 item 50에서는 불변인 날짜 범위 클래스를 만드는데 가변인 Date 필드를 이용했다. 그래서 불변식을 지키고 불변을 유지하기 위해 생성자와 접근자에서 Date 객체를 방어적으로 복사하느라 코드가 상당히 길어졌다. public final class Period { private final Date start; private final Date end; /** * @param start 시작 시각 * @param end 종료 시각; 시작 시각보다 뒤여야 한다. * @throws IllegalArgumentException 시작 시각이 종료 시각보다 늦을 때 발생한다. * @throws NullPointerException start나 end가 null이면 발생한다. */ public Period(Date.. 공감수 0 댓글수 0 2022. 9. 13.
  • item 87. 커스텀 직렬화 형태를 고려해보라 개발 일정에 쫓기는 상황에서는 API설계에 노력을 집중하는 편이 낫다. '애자일'하게 다음 릴리스에서 다시 구현하기로 하고, 이번 릴리스에서는 동작만 하게 만들어놓는.. 그런걸 의미한다. 그러나, 클래스가 Serializable을 구현하고 기본 직렬화 형태를 사용한다면, 다음 릴리스 때 버리려 한 현재의 구현에 영원히 발이 묶인다. (ex BigInteger) 따라서, 먼저 고민해보고 괜찮다고 판단될 때만 기본 직렬화 형태를 사용해야 한다. 직렬화 형태는 유연성, 성능, 정확승 측면에서 고민하면 된다. 일반적으로 직접 설계했다고 하더라도 기본 직렬화 형태와 거의 같은 결과가 나올 경우에만 기본 형태를 써야 한다. 객체의 물리적 표현과 논리적 내용이 같다면? 기본 직렬화 형태라도 무방하다. [ 기본 직렬화.. 공감수 0 댓글수 0 2022. 9. 13.
  • item 82. 스레드 안정성 수준을 문서화하라 보통, API 문서에 synchronized가 붙은 메서드는 '스레드 안전'하다는 말이 있다. 하지만!!! 이는 언제나 맞는 말은 아니다. JavaDoc이 기본 옵션에서 생성한 API문서에는 synchronized 한정자가 포함되지 않기 때문이다. (메서드에 synchronized를 붙이고 말고는 구현 이슈일 뿐, API에 속하는 것이 아니기 때문이다.) 멀티스레드 환경에서도 API를 안전하게 사용하게 하려면, 클래스가 지원하는 스레드 안전성 수준을 정확히 명시해야 한다. 스레드 안전성 수준 나열 ( 안전성이 좋은 순서) 불변(immutabile) 이 클래스의 인스턴스는 마치 상수와 같아서 외부 동기화도 필요 없다. ex) String, Long, BigInteger 무조건적 스레드 안전(uncondit.. 공감수 0 댓글수 0 2022. 9. 1.
  • item 81. wait와 notify보다는 동시성 유틸리티를 애용해라 새로운 사실! wait 그리고 notify는 올바르게 사용하기가 아주 까다롭다. 따라서 고수준 동시성 유틸리티를 사용하는 것이 좋다. wait와 notify란? : 스레드의 상태 제어를 위한 메소드 wait : 가지고 있던 고유 락을 해제하고, 스레드를 잠들게 하는 역할을 하는 메서드 notify : 잠들어 있던 스레드 중 임의로 하나를 골라 깨우는 역할을 하는 메서드 java.util.concurrent의 고수준 유틸리티 실행자 프레임워크 동시성 컬렉션 List, Queue, Map과 같은 표준 컬렉션 인터페이스에 동시성을 가미해 구현한 고성능 컬렉션 높은 동시성에 도달하기 위해 동기화를 각자 내부에서 수행 따라서 동시성 컬렉션에서 동시성을 무력화하는 것은 불가능하다. 외부에서 락을 추가로 사용하면 오.. 공감수 0 댓글수 0 2022. 8. 31.
  • item 80. 스레드보다는 실행자, 테스크, 스트림을 애용하라 java.util.concurrent 패키지의 등장 : 실행자 프레임워크라고 하는 인터페이스 기반의 유연한 테스크 실행 기능 포함. -> 뛰어난 작업 큐를 생성할 수 있게 되었다. // 작업 큐 생성 ExecutorService exec = Executors.newSingleThreadExecutor(); // 실행자에 실행할 테스크를 넘기는 방법 exec.execute(runnable); //실행자를 종료시키는 방법 exec.shutdown(); 실행자 서비스의 주요 기능들 get 특정 테스크가 완료되기를 기다림 invokeAny / invokeAll 테스크 모음 중 아무거나 하나 or 모든 테스크가 완료되기를 기다림 awaitTermination 실행자 서비스가 종료하기를 기다림 ExecutorCom.. 공감수 0 댓글수 0 2022. 8. 31.
  • item 79. 과도한 동기화는 피하라 * 동기화란? 여러개의 thread가 하나의 리소스를 사용하려고 할 때 ,사용하려는 thread를 제외한 나머지 thread들이 리소스에 접근하지 못하게 막는것 * 동기화 방법 메소드 자체를 synchronized로 선언 블록으로 객체를 받아 lock을 거는 방법 - syncrhonized(this) * 과도한 동기화의 문제점 : 성능을 떨어트리고, 교착상태에 빠뜨리며, 데이터를 훼손하고, 예측할 수 없는 동작을 낳는다. 응답 불가와 안전 실패를 피하려면 동기화 메서드나 동기화 블록 안에서는 제어를 절대로 클라이언트에 양도하지 말아라! 제어 ex) 동기화된 영역 안에서 재정의할 수 있는 메서드 호출, 클라이언트가 넘겨준 객체 호출 ----> 동기화된 영역을 포함한 클래스 관점에서, 클라이언트가 넘겨준 메.. 공감수 0 댓글수 0 2022. 8. 31.
  • 공지 앞으로 Effective Java는 개인 notion에 업로드 할 예정입니당~! 나중에 하나씩 다시 올릴 수도 있고... 어짜피 내 티스토리 아무도 안보니까...ㅎㅎㅎㅎㅎㅎ 공감수 0 댓글수 0 2022. 7. 30.
  • item 56. 공개 API 요소에는 항상 문서화 주석을 작성하라 보호되어 있는 글입니다. 공감수 0 댓글수 0 2022. 7. 14.
  • item 55. 옵셔널 반환은 신중하게 해라 메서드가 특정 조건에서 값을 반환할 수 없을 때 취할 수 있는 선택지는 무엇이 있을까? [ 자바 8 이전 ] 예외 던지기 진짜 예외 사항에서 사용하고 있는지 생각해라. 예외를 생성할 때 스택 추적 전체를 캡쳐해야 하므로 비용이 많이 든다. null 반환하기 null처리 코드를 별도로 추가해야 한다. null처리를 무시하고 반환된 null값을 어딘가에 저장하면 언젠가 NullPointerException이 발생할 수 있다. [ 자바 8 이후 ] Optional 원소를 최대 1개 가질 수 있는 '불변' 컬렉션 null이 아닌 T 타입 참조를 하나 담거나, 혹은 아무것도 담지 않을 수 있다. 아무것도 담지 않은 optional은 '비었다'고 하고, 무엇인가 담은 옵셔널은 '비지 않았다'라고 한다. 보통은 T를.. 공감수 0 댓글수 0 2022. 7. 14.
  • item 54. null이 아닌, 빈 컬렉션이나 배열을 반환하라 컬렉션이 비었으면 null을 반환하는 메서드가 있다고 치자. //null 반환 public List getCheeses() { return cheesesInStock.isEmpty() ? null : new ArrayList(cheesesInStock); } 클라이언트는 이 null 상황을 처리하는 코드를 추가적으로 작성해야 한다. 컬렉션이나 배열 같은 컨테이너가 비었을 때 null을 반환하는 메서드를 사용할 때면 항시 이와 같은 방어 코드를 넣어줘야 한다. 클라이언트에서 방어 코드를 빼먹으면 오류 상황이 발생할 수 있다. (수년 후에도 발생할 수 있음.) 마치 얼마 전에 풀었던 트리 복구라는 백준 문제가 생각난다. null처리를 안해줘서 틀렸던 친구들이 많았던 것 같아서(?) 그에 반해, 빈 컨테이너를.. 공감수 0 댓글수 0 2022. 7. 14.
  • item 53. 가변인수는 신중히 사용하라 가변인수 메서드는 명시한 타입의 인수를 0개 이상 받을 수 있다. 가변인수 메서드를 호출하면, 가장 먼저 인수의 개수와 길이가 같은 배열을 만들고, 인수들을 이 배열에 저장하여 가변인수 메서드에 건네준다. public static void main(String[] args) { System.out.println(sum(1, 2)); //3 System.out.println(sum(1)); //1 System.out.println(sum()); //0 } static int sum(int... numbers) { int sum = 0; for (int number : numbers) { sum += number; } return sum; } 입력받은 인수들의 합을 return해주는 메서드이다. 인수가 1개.. 공감수 0 댓글수 0 2022. 7. 13.
  • item 52. 다중 정의는 신중히 사용해라 다중 정의는 모두 아시죠? 다른 말로는 오버로딩이라는 친숙한 이름을 갖고있다. 오버로딩이 뭐였더라? 서로 다른 시그니처를 갖는 여러 메소드들이 같은 이름으로 정의되는 것 이다. 즉, 메서드명은 같지만 매개변수의 개수, 타입, 순서들이 다른 메서드들을 의미한다. 다중 정의된 메소드는 어느 메서드를 호출할 지가 컴파일 타임에 정해진다. public class item52 { public static void main(String[] args) { Collection[] collections = { new HashSet(), new ArrayList(), new HashMap().values() }; for (Collection c : collections) { System.out.println(item52... 공감수 0 댓글수 0 2022. 7. 10.
  • item 51. 메서드 시그니처를 신중히 설계하라 API 설계 요령들 메서드 이름을 신중히 짓자. 항상 표준 명명 규칙을 따라야 한다. 편의 메서드를 너무 많이 만들지 말자. 메서드가 너무 많은 클래스는 익히고, 사용하고, 문서화하고, 테스트하고, 유지보수하기 어렵다. 클래스나 인터페이스는 자신의 각 기능을 완벽히 수행하는 메서드로 제공해야 한다. 확신이 서지 않으면 만들지 말아라 매개변수 목록은 짧게 유지하자. 4개 이하가 좋다. 같은 타입의 매개변수 여러개가 연달아 나오는 경우는 해롭다. 과하게 긴 매개변수 목록을 짧게 줄여주는 기술 3가지 여러 메서드로 쪼개기 매개변수 여러 개를 묶어주는 도우미 클래스를 만들기(일반적으로 정적 멤버 클래스) 객체 생성에 사용한 빌더 패턴을 메서드 호출에 응용한다. (매개변수가 많고 그 중 일부를 생략해도 괜찮을 때.. 공감수 0 댓글수 0 2022. 7. 10.
  • item 50. 적시에 방어적 복사본을 만들라 자바 : 안전한 언어! 네이티브 메서드를 사용하지 않기 때문이라고 한다. 네이티브 메서드를 사용하지 않기 때문에 버퍼/배열 오버런, 와일드 포인터와 같은 메모리 충돌 오류에서 안전하다고 한다. 자바로 작성한 클래스에서는 시스템의 다른 부분에서 무슨 짓을 하든 그 불변식이 지켜진다. 따라서 메모리 전체를 하나의 거대한 배열로 다루는 언어에서는 누릴 수 없는 강점이다. (자바의 강점이 뭘까? 라고 하면 얘를 대답하면 좋지 않을까 해서 적어봄) 네이티브 메서드가 뭘까?.? 네이티브 메소드란? 네이티브 메소드는 자바가 아닌 다른 언어로 구현된 메소드라고 한다. 네이티브 메소드 앞에는 native 키워드가 붙어있다! 더 찾아보려 했는데 item 66에서 다루더라? 그래서 더 찾아보지는 않았다. 시스템 보안을 뚫으.. 공감수 0 댓글수 0 2022. 7. 10.
  • item 49. 매개변수가 유효한지 검사하라 메서드와 생성자 대부분은 매개변수의 값을 정하는 데 제약을 주는데, 이는 가능한 한 오류를 빠르게 잡아야 하기 때문이다. 따라서 메서드 몸체가 실행되기 전에 매개변수를 확인하여 즉각적으로 예외를 던질 수 있게 해야한다. 매개변수 검사를 제때 하지 못하면 몇 가지 문제가 발생할 수 있다. 1. 메서드가 수행되는 중간에 모호한 예외를 던지며 실패할 수 있다. 2. 메서드가 잘 수행되지만 잘못된 결과를 반환할 수 있다. 3. 메서드는 문제없이 수행됐지만, 어떤 객체를 '이상한' 객체로 만들어 미래에 알 수 없는 시점에 해당 메서드와 관련 없는 오류를 낼 수 있다. 즉, 매개변수 검사에 실패하면 실패 원자성(failure atomicity)를 어기는 결과를 낳을 수 있다. public, protected 제어자.. 공감수 0 댓글수 0 2022. 7. 7.
  • item 48. 스트림 병렬화는 주의해서 적용해라 자바 5부터는 동시성 컬렉션인 java.util.concurrent 라이브러리와 실행자(Executor) 프레임워크를 지원했다. 자바 7부터는 고성능 병렬 분해 프레임워크인 포크-조인 패키지를 추가했다. 포크조인(ForkJoin) 프레임워크는 병렬 처리를 위한 모델이고 분할 정복 알고리즘을 통해서 재귀적으로 처리 자바 8부터는 parallel 메서드만 한 번 호출하면 파이프라인을 병렬 실행할 수 있는 스트림을 지원했다. 병렬 스트림은 요소들을 병렬 처리하기 위해 포크조인(ForkJoin) 프레임워크를 사용 이처럼 자바로 동시성 프로그램을 작성하기가 점점 쉬워지고는 있지만, 이를 올바르고 빠르게 작성하는 일은 여전히 어려운 작업이다. 스트림 병렬화의 문제점. 데이터 소스가 Stream.iterate거나 중.. 공감수 0 댓글수 0 2022. 7. 2.
  • item 47. 반환 타입으로는 스트림보다 컬렉션이 낫다 자바는 7까지 원소 시퀀스(일련의 원소)를 반환하는 메서드의 반환 타입으로 Collection, List, Set 등의 컬렉션 인터페이스나 Iterable 배열을 사용했다. 기본은 Collection 인터페이스다. forEach에서만 쓰이거나, contains같은 일부 collection 메소드를 구현할 수 없을 때는 Iterable을 썼고, 기본 타입이거나 성능에 민감할 때는 배열을 사용했다. 그런데? 자바 8에서 스트림이 생기면서, 선택지가 복잡해졌다. item 45에서 봤듯이 stream은 반복을 지원하지 않는다. forEach같은 애들은 List, Set과 같은 Iterable구현체에 대해서만 사용이 가능하다.따라서 스트림과 반복을 적절히 섞어야 좋은 코드가 된다. 여기서 재미없는 사실 하나! 사.. 공감수 0 댓글수 0 2022. 7. 2.
  • item 46. 스트림에서는 부작용 없는 함수를 사용하라 스트림은 그저 또 하나의 API가 아닌, 함수형 프로그래밍에 기초한 패러다임이다. 즉.. 스트림이 제공하는 표현력, 속도, 병렬성 등을 얻기 위해서는 '스트림 패러다임'을 받아들여야 한다. 스트림 패러다임의 핵심이란? : 계산을 일련의 변환으로 재구성 하는 부분 각 변환 단계는 가능한 한 이전 단계의 결과를 받아 처리하는 순수 함수 (*다른 가변 상태를 참조하거나 스스로 상태를 변경하지 않고, 오직 입력만이 결과에 영향을 주는 함수)여야 한다. 이를 위해선 스트림 연산에 건네는 함수는 모두 부작용이 없어야 한다. forEach 연산은 스트림 계산 결과를 보고할 때만 사용하고, 계산하는 데는 쓰지 말자. 스트림 패러다임을 이해하지 못한 채 API만 사용한 예시를 보자. "스트림 코드를 가장한 반복적 코드".. 공감수 0 댓글수 0 2022. 7. 2.
  • item 45. 스트림은 주의해서 사용하라. 스트림이 뭘까요? : 데이터 처리 작업(순차 또는 병렬)을 지원하고자 Java8부터 추가된 API 스트림이 제공하는 추상 개념의 핵심 두가지 1. 데이터 원소의 유한 혹은 무한 시퀀스 2. 원소들로 수행하는 연산 단계를 표현하는 스트림 파이프 라인 스트림의 원소는 컬렉션, 배열, 파일, 정규표현식 패턴 매처, 난수 생성기 등 어디로부터든 올 수 있다. 스트림 안의 데이터 원소들은 객체 참조나 int, long, double의 기본 타입 값이다. 스트림 파이프 라인의 생애 주기(?) 소스 스트림 -> 1개 이상의 중간 연산 -> 종단 연산 스트림 중간 연산들은 모두 한 스트림을 다른 스트림으로 변화시키는데, 변환된 스트림의 원소 타입 값은 기존과 다를 수 있다. 종단 연산은 마지막 중간 연산이 내놓은 스.. 공감수 0 댓글수 0 2022. 6. 18.
  • item 44. 표준 함수형 인터페이스를 사용하라 핵심만 쏙쏙.. 불필요한 함수형 인터페이스를 직접 구현해 사용하지 말고, 대신 표준형 함수형 인터페이스를 사용하라. 왜? 자바 표준 라이브러리에 이미 같은 모양의 인터페이스가 있을 것이다. 필요한 용도에 맞는 인터페이스가 있는지 먼저 확인해라. 심지어, 표준 함수형 인터페이스들은 유용한 디폴트 메서드도 많이 제공한다. 이는 다른 코드와의 상호 운용성도 높인다. java.util.function 패키지의 인터페이스 43가지! 다 기억하긴 어렵고, 기본 인터페이스 6개는 꼭 기억해두자. (모두 참조용 타입이다.) 인터페이스 함수 시그니처 의미 예시 UnaryOperator T apply(T t) 반환 값과 인수의 타입이 같은 함수, 인수는 1개 String::toLowerCase BinaryOperator .. 공감수 0 댓글수 0 2022. 6. 18.
  • item 43. 람다보다는 메서드 참조를 사용하라 자바에서 함수를 간결하게 하는 방법! : 메서드 참조 > 람다 > 익명 클래스 Map의 merge 메소드를 통하여 예시를 살펴보자. Map map = new HashMap(); map.put(1, 2); map.put(3, 4); map.put(5, 6); int key = 1; map.merge(key, 2, (count, incr) -> count + incr); [코드 설명] Map 타입 객체에 key를 매핑한다. Map 안에 key가 존재한다면, value와 기존 key에 매핑되는 value를 더한다. 존재하지 않을 경우에는 key, value를 추가한다. : 깔끔해 보이지만, 매개변수 count와 incr은 크게 하는 일 없이 공간을 많이 차지하기 때문에, 거추장스럽다. : 또한 여기서 사용된 .. 공감수 0 댓글수 0 2022. 6. 17.
  • item 42. 익명 클래스보다는 람다를 사용하라 익명 클래스는 무엇일까? - 람다가 나오기 이전, 자바에서 함수 객체를 만드는 주요 수단 - '낡은' 기법이다. //익명 클래스 예시 Collections.sort(words, new Comparator() { public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()); } }); - 코드가 너무 길기 때문에 함수형 프로그래밍에는 적합하지 않은 방법이다. 람다는 무엇일까? - 추상 메서드 하나짜리 인터페이스(함수형 인터페이스)들의 인스턴스. - 람다식 이라고도 한다. - 함수, 익명 클래스와 개념은 비슷하지만 코드가 간결하다. - 어떤 동작을 하는지 명확히 드러난다. //람다 예시 Collection.. 공감수 0 댓글수 0 2022. 6. 14.
  • item 41. 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라 마커 인터페이스란? - 아무 메서드도 담고 있지 않으며, 자신을 구현하는 클래스가 특정 속성을 가지는 것을 표시해주는 인터페이스 - 예시로는 Serializable, Cloneable interface 등이 있다. //Serializable Interface를 봐보자! package java.io; public interface Serializable { } 마커 애너테이션이란? - 해당 요소가 특정 속성을 가지는 것을 나타내는 애너테이션 - 마커 어노테이션은 멤버를 포함하지 않으며 데이터로 구성되지 않는다. - 마커 어노테이션의 목적은 단지 어노테이션 선언을 표시하는 것이다. - 예시로는 @Override 등이 있다. //@Override Annotation package java.lang; impor.. 공감수 0 댓글수 0 2022. 6. 14.
  • item 40. @Override 애너테이션을 일관되게 사용하라 @Override 애너테이션을 알고 있을 것이다. 메서드 선언부에 다는 상위 타입의 메서드를 재정의할 때 사용하는 애너테이션이다. 구체 클래스에서 상위 클래스의 추상 메서드를 재정의할 때를 제외하고는, 상위 클래스의 메서드를 재정의하려는 모든 메서드에 @Override 애너테이션을 달자. 추상 메서드는 구체 클래스인데 아직 구현하지 않은 메서드가 남아있다면 컴파일러가 알려주기 때문에 굳이 애너테이션을 달지 않아도 된다. IDE를 사용하면 조금 더 편하게 애너테이션을 달 수 있다. 메서드에 애너테이션이 달려있지 않다면 경고를 주기도 하고... 그렇다. @Override 애너테이션은 클래스 뿐만 아니라 인터페이스의 메서드를 재정의할 때도 사용할 수 있다. 이 때도 애너테이션은 꼭 다는 습관을 갖도록 하자! .. 공감수 0 댓글수 0 2022. 6. 12.
  • item39. 명명 패턴보다 애너테이션을 사용하라 명명 패턴이 뭘까요? 메서드나 타입의 이름을 특정 규칙으로 짓고, 이 규칙을 지켜 만든 메소드나 타입 등에 추가적인 처리를 제공하는 것 ex) JUnit은 test method의 이름을 test로 시작하게끔 하는 것.... 명명 패턴은 효과적이지만, 단점도 많다. 명명 패턴의 단점 오타 메서드나 타입을 이름으로 구분하기 때문에, 오타가 나면 자칫 이 메서드는 무시된 채로 넘어갈 수 있다. JUnit의 test method의 경우 이름 실수가 났을 경우 테스트의 성공/실패 자체를 알 수 없기 때문에, 성공된줄 알고 지나칠 수도 있다. 올바른 프로그램 요소에서만 사용될 것이라는 보증이 없음 Junit에서는 테스트 메서드 이름을 test로 시작해야 할뿐, 클래스 이름은 이를 따를 필요가 없지만, 사용자가 클래.. 공감수 0 댓글수 0 2022. 6. 3.
  • item 38. 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라 책에 의하면, 열거 타입은 거의 모든 상황에서 타입 안전 열거 패턴보다 우수하다. 그러나 예외 상황이 하나 있다. 확장 가능해야 하는 상황 이다. 확장 가능한 상황에서는 타입 안전 열거 패턴이 더 우수하다. 타입 안전 열거 패턴은 열거 타입과 달리 열거한 값들을 그대로 가져온 다음, 값을 더 추가하여 다른 목적으로 쓸 수 있다. 열거 타입이 확장하기 힘들게 설계된 이유는 무엇일까? - 기반 타입과 확장된 타입들의 원소를 모두 순회할 방법이 마땅치 않기 때문이다. - 확장성을 높이려면 고려할 요소가 늘어나 설계나 구현이 더 복잡해진다. ! 확장된 열거 타입이 필요한 경우 ! - 연산 코드 (opCode) - 연산 코드의 각 원소는 특정 기계가 수행하는 연산을 뜻한다. API가 제공하는 기본 연산 외에 사용.. 공감수 0 댓글수 0 2022. 6. 3.
  • item 37. ordinal 인덱싱 대신 EnumMap을 사용하라 Ordinal 메소드를 기억하고 있나요 : 열거 타입 내에서 열거형 인스턴스의 순서를 반환하는 메소드 인 것을 기억 할 것이다. 어떤 상수의 위치를 반환한다고 생각하면 된다. 정원에 심은 식물들을 생애 주기별로 관리하는 예제를 확인해보자. public static class Plant { // 식물의 생애 주기를 관리하는 열거 타입 enum LifeCycle { ANNUAL, PERENNIAL, BIENNIAL } final String name; final LifeCycle lifeCycle; Plant(String name, LifeCycle lifeCycle) { this.name = name; this.lifeCycle = lifeCycle; } @Override public String toSt.. 공감수 0 댓글수 0 2022. 6. 3.
    728x90
    문의안내
    • 티스토리
    • 로그인
    • 고객센터

    티스토리는 카카오에서 사랑을 담아 만듭니다.

    © Kakao Corp.