Java
-
[Effective Java] 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라Java 2023. 2. 2. 11:02
상속을 고려한 설계와 문서화란? 1. 메서드를 재정의하면 어떤 일이 일어나는지를 정확히 정리하여 문서로 남겨야 한다. 즉, 상속용 클래스는 재정의할 수 있는 메서드들을 내부적으로 어떻게 이용하는지(자기사용) 문서로 남겨야 한다. 클래스의 API로 공개된 메소드에서 클래스 자신의 또 다른 메소드를 호출할 수도 있다. 이때 호출되는 메소드가 하위 클래스에서 재정의 가능한 메소드라면 이 사실을 호출하는 메소드의 API 설명에 명시해야 한다. 재정의 가능 메소드를 호출할 수 있는 모든 상황을 문서로 남겨두어야 한다. API 문서의 메서드 설명 끝에서 종종 "Implementation Requirements"로 시작하는 절을 볼 수 있는데, 그 메서드의 내부 동작 방식을 설명하는 곳이다. (메서드 주석에 @imp..
-
[Effective Java] clone 재정의는 주의해서 진행하라Java 2023. 2. 2. 11:01
Clonable은 메서드가 없는 인터페이스이다. clone 메서드는 원본 객체의 필드 값과 동일한 값을 가지는 새로운 객체를 생성해준다. clone 메서드를 사용하기 위해서는 해당 클래스에서 Cloneable 인터페이스를 구현해주어야 한다. 클래스에서 clone을 재정의하기 위해선 해당 클래스에 Cloneable 인터페이스를 상속받아 구현하여야 한다. 그런데 정작 clone 메소드는 Cloneable 인터페이스가 아닌 Object에 선언되어있다. Cloneable 인터페이스는 아무것도 선언되어 있지 않은 빈 인터페이스이다. Cloneable 인터페이스의 역할 /** * A class implements the Cloneable interface to * indicate to the {@link java...
-
[Effective Java] toString을 항상 재정의하라Java 2023. 2. 2. 11:00
Object 클래스의 기본 toString 메서드 Object 클래스 자바의 Object 클래스는 모든 자바 클래스의 최상위 클래스로, 전체 이름은 java.lang.Object 이다. Object클래스는 가장 최상위 클래스이므로 자바의 모든 클래스들은 Object 클래스를 상속받는데, 컴파일 과정에서 컴파일러가 자동으로 extends 해준다. toString 메서드 toString은 말 그대로 객체의 정보를 String(문자열)형으로 형변환 해준다. Object 클래스를 상속받은 클래스들은 toString()을 오버라이딩(재정의)하여 사용할 수 있다. 자주 쓰이는 String이나 Integer 클래스에는 toString()이 이미 재정의 되어 있다. 예) Book 클래스 public class Book..
-
[Effective Java] try-finally보다는 try-with-resources를 사용하라Java 2023. 2. 2. 11:00
자바 라이브러리에는 InputStream, OutputStream, java.sql.Connection 등 close메서드를 호출해 직접 닫아줘야 하는 자원이 많다. 전통적으로 이러한 자원을 닫기 위한 수단으로 try-finally가 사용되었다. try-finally - 자원을 회수하는 최선의 방책이 아니다 static String firstLineOfFile(String path) throws IOException{ BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { br.close(); } } 자원이 둘 이상이면 try-finally 방식은 코드가 매우 복잡해진다. sta..
-
[Effective Java] 다 쓴 객체 참조를 해제하라Java 2023. 2. 2. 10:58
C, C++와 같은 언어는 메모리를 직접 관리해야 하지만, 자바는 가비지 컬렉터를 갖추어서 다 쓴 객체를 알아서 회수한다. 자칫 메모리 관리에 더 이상 신경 쓰지 않아도 된다고 오해할 수 있는데, 사실이 아니다. 예제 public class Stack{ private Object[] elements; private int size = 0; private Stack(){ elements = new Object[DEFAULT_INITIAL_COPACITY]; } public Object pop(){ if (size==0) throw new EmptyStackException(); return elements[--size]; } private void ensureCapacity(){ if (elements.l..
-
[Effective Java] 인스턴스화를 막으려거든 private 생성자를 사용하라Java 2023. 2. 2. 10:58
인스턴스화를 막는 이유 정적 메서드와 정적 필드만을 담은 클래스를 만들고 싶을 때가 있다. 예를 들어 java.lang.Math, java.util.Arrays 처럼 기본 타입 값이나 배열 관련 메서드들을 모아놓을 수 있다. 이러한 성격의 클래스는 인스턴스화를 막는게 일반적이다. 인스턴스를 만든다는 것은 객체마다 다른 속성값을 가지고 있을 때 의미가 있다. 정적 필드와 메소드로만 구성된 클래스는 객체를 만드는것이 의미가 없다. 심지어 메모리상 낭비를 가져온다. 따라서 정적인 방식으로 만들어진 클래스는 인스턴스화를 막는것이 옳다. 추상 클래스로 만드는 것으로는 인스턴스화를 막을 수 없다. 하위 클래스를 만들어 인스턴스화하면 그만이기 때문이다. 이를 본 사용자는 상속해서 쓰라는 뜻으로 오해할 수 있으니 더 ..
-
[Effective Java] private 생성자나 열거 타입으로 싱글턴임을 보증하라Java 2023. 2. 2. 10:57
싱글턴(Singleton)이란? 싱글턴이란 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다. 싱글턴패턴이란? 생성자의 호출이 반복적으로 이루어져도 실제로 생성되는 객체는 최초 생성된 객체를 반환함을 의미한다. public class Animal{ private static Animal animals = null; private Animals(){} public static Animals getInstance(){ if(animals == null){ animals = new Animals(); } return animals; } } Animals라는 클래스가 있고 private static을 사용하여 최초로 메모리를 한번만 할당한다. 싱글턴 사용하는 이유 객체 생성으로 재 사용이 가능하기 때문에 ..