728x90
반응형

Effective Java 9

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

null을 반환하는 코드는 클라이언트가 null 상황을 처리하는 코드를 추가하도록 한다. 컬렉션이나 배열 같은 컨테이너가 비었을 때 null을 반환하는 메서드를 사용할 때면 방어 코드를 추가해야 한다. 빈 컬렉션을 반환하는 코드 public List getList() { return object.isEmpty() ? Collections.emptyList() : new ArrayList(object); } 길이가 0일 수도 있는 배열을 반환하는 코드 private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; public Object[] getObjects() { return object.toArray(EMPTY_OBJECT_ARRAY); } 마무..

[Effective Java] equals는 일반 규약을 지켜 재정의하고 hashCode도 재정의하라

equals 메서드는 재정의하기 쉬워 보이지만 곳곳에 함정이 도사리고 있어서 자칫하면 끔직한 결과를 초래할 수 있습니다. 문제를 회피하는 가장 쉬운 길은 재정의하지 않는 것으로, 그렇게 두면 클래스의 인스턴스는 오직 자기 자신과만 같게 됩니다. 재정의하지 않는 것이 최선인 경우 1. 각 인스턴스가 본질적으로 고유하다. 값을 표현하는 것이 아니라, 동작하는 개체를 표현하는 클래스를 표현할 때는 재정의 하지 않는 것이 더 좋습니다. 예로 Thread가 있고, equals 메서드는 Thread에 가장 딱 맞게 구현되어 있습니다. 2. 인스턴스의 '논리적 동치성'을 검사할 일이 없다. Pattern 클래스를 사용할 때 만약 equals를 재정의해서 사용하는 것은, 두 인스턴스가 같은 정규표현식을 나타내는지 검사..

[Effective Java] try-finally 보다는 try-with-resources를 사용하라

자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야 하는 자원이 많습니다. InputStream, OutputStream 등이 좋은 예입니다. 자원 닫기는 클라이언트가 놓치기 쉬워 예측할 수 없는 성능 문제로 이어지기도 합니다. 전통적으로 자원이 제대로 닫힘을 보장하기 위해 try-finally를 사용했습니다. try-finally 코드 예시 public class TryFinallyTest { static void copyFiles(String rawPath, String copyPath) throws IOException { InputStream in = new FileInputStream(rawPath); try{ OutputStream out = new FileOutputStream(co..

[Effective Java] 다 쓴 객체 참조를 해제하라

자바는 C와 C++과는 다르게 가비지 컬렉터를 갖추고 있어서 메모리를 관리하지 않아도 된다. 그렇다고 메모리 관리에 신경쓰지 않아도 된다는 것은 아니다. 이것은 오해이다. 메모리 누수가 일어나고 있는 코드 public class MemoryLeakTest { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public MemoryLeakTest() { elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Object e){ ensureCapacity(); elements[size++] = e; } p..

[Effective Java] 불필요한 객체 생성을 피하라

똑같은 기능의 객체를 매번 생성하기보다 객체 하나를 재사용하는 편이 나을 때가 많습니다. String 객체 생성 시 String string = new String("value"); 다음과 같은 코드는 실행될 때마다 String 인스턴스를 새로 만들게 됩니다. 그래서 반목문이나, 자주 호출되는 메서드에 포함되어 있다면 사용하지 않는 인스턴스가 많이 생성될 수 있습니다. String string = "value"; 다음과 같은 코드를 통해 위에서 문제점을 개선할 수 있습니다. 새로운 인스턴스를 생성하는 대신 하나의 String 인스턴스를 재활용하여 사용합니다. 이와 같은 방식을 사용할 때, 가상 머신 안에서 이와 똑같은 문자열 리터럴을 사용하는 모든 코드가 같은 객체를 재사용함이 보장됩니다. Boolean..

[Effective Java] 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라

많은 클래스가 하나 이상의 자원에 의존합니다. 이번 시간에는 의존하는 방식에 대해서 고민해보는 시간입니다. 1. 정적 유틸리티를 잘못 사용한 예 package twim.corp.grafting.domain.Grafting.service; public static class DependencyCheck { private final DependencyLib dependencyLib = new DependencyLib(); private DependencyCheck(){}; public boolean isValid(String dependency){ return true; } } 2. 싱글턴을 잘못 사용한 예 package twim.corp.grafting.domain.Grafting.service; publ..

[Effective Java] private 생성자나 열거타입으로 싱글턴임을 보증하라

싱글턴(singleton) 이란 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말합니다. 싱글턴을 만드는 방식 1. public static 멤버가 final 필드인 방식 public class SingletonTest { public static final SingletonTest INSTANCE = new SingletonTest(); private SingletonTest(){}; // private 생성자 } 2. 정적 팩터리 방식 public class SingletonTest { private static final SingletonTest INSTANCE = new SingletonTest(); private SingletonTest(){}; // private 생성자 public stat..

[Effective Java] 생성자에 매개변수가 많다면 빌더를 고려하라

정적 팩터리 메서드와 생성자는 선택적 매개변수가 많을 때 적절히 대응하기 어렵다는 단점이 존재합니다. 점층적 생성자 패턴 생성자의 매개변수의 개수를 조절하여 객체를 생성하는 방식입니다. 이 방식은 매개변수의 순서도 중요하고 매개변수가 무엇을 의미하는지 알기도 어렵기 때문에 작성하기 어렵습니다. public class TestClass { private int x; private int y; private int z; public TestClass(int x) { this.x = x; } public TestClass(int x, int y) { this.x = x; this.y = y; } public TestClass(int x, int y, int z) { this.x = x; this.y = y; ..

[Effective Java] 생성자 대신 정적 팩터리 메서드를 고려하라

클래스는 생성자와 별도로 클래스의 인스턴스를 반환하는 정적 팩터리 메서드를 제공할 수 있습니다. 팩터리 메서드 장점 1. 이름을 가질 수 있다 `String.java의 valueOf @Notnull @Contract(pure = true) public static String valueOf(@NotNull char data[]){ return new String(data); } `Main.java //생성자를 사용하지 않고, 정적 팩토리 메서드를 통해 인스턴스 반환 public static void main(String[] args) { String str = String.valueOf("value assign"); System.out.println(str); } 위와 같이 정적 팩터리 메서드를 사용하면..

728x90
반응형