본문 바로가기

반응형

IT

[Effective Java] item 10 equals는 일반 규약을 지켜 재정의하라 equals 메서드를 재정의해서 사용하는 경우가 많은 아래의 경우엔 기본 equals 메소드를 사용하는 걸 추천한다. 1) 각 인스턴스가 본질적으로 고유한 경우 (thread -> 동작 클래스) 2) 인스턴스의 논리적 동치성을 검사할 일이 없는 경우 3) 상위클래스에서 재정의한 equals 가 하위 클래스에도 맞는 경우 4) 클래스가 private이거나 package-private이고 equals 메서드를 호출할 일이 없는 경우 하지만 equals 메서드를 재정의해야 된다면 아래의 규약을 따라야 한다. 1) 반사성 : 자기자신에 대한 비교 = 항상 참 2) 대치성 : 서로 비교 대상을 바꾸더라도 = 항상 참 3) 추이성 : 서로 참이라면 연결관계에 있는 제3의 객체도 참이여야 한다. 더보기 추이성을 보장.. 더보기
[Effective Java] item 8, 9 finalizer & cleaner 사용을 피해라 / try-finally 보다는 try-with-resources를 사용해라 자바는 두가지 객체 소멸자를 제공한다. 1) finalizer 2) cleaner finalizer 는 예측할 수 없고 상황에 따라 위험할 수 있어 사용을 권장하지 않는다. 반면에 cleaner는 finalizer 보단 안전하지만 여전히 예측할 수 없음으로 사용을 권장하지 않는다. 해결방법으론 item 9인 try-with-resources 를 사용하는 것인데 먼저 왜 사용하면 안되는지 설명하고자 한다. 문제점 1 finalizer, cleaner은 언제 수행될지 알기 어렵다. 왜냐하면 finalizer 쓰레드는 우선순위가 낮기 때문에 실행될 기회를 자꾸 놓치고 cleaner 스레드는 동일한 순위에 있지만 백그라운드에서 수행되고 가비지컬렉터의 통제를 받기 때문에 즉각 수행됨을 보장하지 못한다. 수행 시점.. 더보기
[Effective Java] item 7 다 쓴 객체 참조를 해제하라 자바가 가비지 컬렉터를 갖춘 언어라고 해서 메모리 관리는 무시해서는 안된다. 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 o){ ensureCapacity(); elements[size++] = o; } public Object pop(){ if (size == 0) throw new EmptyStackException(); return elements[--size].. 더보기
[Effective Java] item6 불필요한 객체 생성을 피하라 String s = new String("bikini"); => 실행될 때마다 String 인스턴스를 새로 만든다. 이 문장은 반복문이나 비번하게 호출할 경우 수백만개의 String 인스턴스가 생성될 수 있는 코드이다. String s = "bikini"; 로 코드를 수정함으로서 같은 객체를 재사용하도록 개선할 수 있다. 불필요한 객체 생성을 피할 수 있는 방법은 여러개가 있다. 1) 정적 팩터리 메서드를 사용해서 불필요한 객체 생성을 피할 수 있음 ex) Boolean(String) 생성자 대신에 Boolean.valueof(String) 팩터리 메서드를 사용 = 생성자는 호출때마다 새로운 객체를 생성하지만, 팩터리 메서드는 그렇지 않다. 2) 캐싱을 통해 재사용할 수 있음 static boolean .. 더보기
JPA 영속성 관리 JPA를 사용하면 컨테이너가 트랜젝션과 영속성 컨텍스트를 관리해주므로 애플리케이션을 손쉽게 개발할 수 있음 BUT JPA의 내부 동작을 이해하지 못하면 문제가 발생했을 때 해결하기가 쉽지 않음 먼저, 스프링이나 J2EE 환경에서 JPA를 사용하면 컨테이너가 제공하는 전략을 따라야 한다. 제공하는 기본 전략은 바로 트랜젝션 범위의 영속성 컨텍스트 전략이다. (트랜젝션 범위 = 영속성 컨텍스트 범위) 보통 서비스계층에서 @Transactional 어노테이션으로 트랜젝션을 시작하는데 어노테이션이 있는 메소드를 호출하면 메소드 실행 전에 트랜젝션이 먼저 시작된다. 즉, 서비스단 메소드 호출 -> 트랜젝션 시작 -> 메소드 실행 -> 메소드 종료 -> 트랜젝션 커밋 (영속성 컨텍스트 플러시 발생 -> DB 반영 .. 더보기
[Effective Java] Item 5 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 Item 5 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않다. 예를 들어 스펠링 검사 클래스를 구현할때 사전이라는 객체는 불변의 객체로 공유되어야 한다. 하지만, 이때 사전은 언어별로 또는 특수 어휘용으로 검사의 기준이 되는 사전은 달라질 수 있다. 정적 유틸리티 public class SpellChecker { private static final Lexicon dictionary = ...; private SpellChecker() { } ... } 싱클턴 패턴 public class SpellChecker { private static final Lexicon dictionary = ...; p.. 더보기
[Effective Java] Item 4 인스턴스화를 막으려거든 private 생성자를 사용하라 객체지향적으로 봤을때 정적 메서드나 정적필드만을 모아두는 클래스는 좋지 않지만, 나름 필요한 경우가 있다. 1) java.lang.Math나 java.util.Arrays처럼 기본 타입 값이나 배열 관련 메서드들을 모아놓는 경우 2) java.util.collections처럼 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드를 모아놓는 경우 3) final 클래스와 관련한 메서드들을 모아놓은 경우 (final 클래스는 상속해서 하위 클래스에 메서드를 추가하는 것이 불가능하기 때문에) 정적 멤버만을 담을 유틸리티 클래스는 인스턴스를 생성해서는 안된다. 하지만, 생성자를 명시하지 않으면 자바에서 자동으로 public 생성자를 만들기 때문에 의도치 않게 인스턴스화를 할 수 있는 경우가 발생한다. 이 문.. 더보기
[Effective Java] Item 3 Private 생성자나 열거 타입으로 싱글턴임을 보장하라 Item 3 Private 생성자나 열거 타입으로 싱글턴임을 보장하라 싱글턴이란 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다. (= 설계상 유일해야 하는 컴포넌트) 싱글턴을 만드는 방법은 3가지가 있다. 1) 유일한 인스턴스에 접근할 수 있는 수단으로 public static 멤버를 만드는 방법 public class NutritionFacts { public static final NutritionFacts INSTANCE = new NutritionFacts(); private NutritionFacts(){ } } private 생성자는 public static final 필드인 NutritionFacts.INSTATCE 를 초기화할 때 딱 한번만 호출됨으로 하나뿐임을 보장한다. 장점 싱.. 더보기

반응형