티스토리 뷰
'정적 메서드와 정적 필드만'을 담은 클래스를 만들라는 요구사항이 들어온다고 생각해봅시다.
'객체 지향의 사실과 오해'를 당연히 읽은(?) 우리에게는 말도 안되는 요구사항입니다. 객체 지향의 세계에서는 모든 객체가 역할을 가지고 협력하는데, 역할을 수행할 객체가 없는 상황에서 역할을 기대하는 것은 더이상 객체지향을 지킨다고 볼 수 없습니다.
이런 생각을 가진 상태에서 아래의 코드를 봅시다.
public static void main(String[] args) {
Integer mini = Math.min(1, 2);
System.out.println("mini = " + mini);
}
자바가 제공하는 Math class의 min 메서드를 사용하는 간단한 코드입니다. 하지만, 우리는 Math 인스턴스를 생성한 적이 없습니다.
한번 Math class의 min 메서드를 한번 열어봅시다.
public static int min(int a, int b) {
return (a <= b) ? a : b;
}
min 메서드가 정적 메서드이기 때문에 이것이 가능했던 것이군요. 코드를 열어본 김에 좀더 관찰을 해보니 이상한점을 발견했습니다.
public final class Math {
/**
* Don't let anyone instantiate this class.
*/
private Math() {}
...
}
Math 클래스는 생성자가 private로 설정되어 있습니다. 그리고 주석으로 이 클래스를 인스턴스화 하지말라고 적혀있습니다.
자바의 핵심 철학은 '객체 지향' 입니다. 하지만 이런 자바에서 조차 객체지향을 위반하는 것처럼 보이는 코드를 사용하고 있습니다. 이말은 다르게 해석하면 이러한 방식이 분명 쓸모가 있다는 것이죠.
Math에 달려있는 주석을 보면 알 수 있듯이 정적 메서드와 필드만을 담은 Util 클래스는 인스턴스로 만들어 사용하려고 설계한 것이 아닙니다. 그렇다고 생성자를 만들지 않으면 컴파일러가 자동으로 기본 생성자를 만들기 때문에, 생성자를 만들긴 해야 합니다.
그래서 private 생성자를 아래와 같이 추가하는 방법을 생각해봤습니다.
public class Hello {
private Hello(){}
}
하지만, 이 방법은Item3에서 봤던 Reflection API를 호출하면 그만입니다. 그래서 아예 생성자를 호출하지 못하게 만들어야 합니다.
public class Hello {
private Hello(){
// Don't let anyone instantiate this class.
throw new IllegalStateException("호출할 수 없는 생성자입니다.");
}
}
이제 명시적 생성자가 private로 선언되었으니 클래스 바깥에서 접근할 수가 없고, 클래스 내부에서 조차 생성자를 호출할 수 없게 되었습니다. 따라서 Reflection API의 공격도 방지할 수 있습니다.
하지만, 다른 협업자가 이 코드를 보면 의아할 수도 있습니다. 분명 생성자가 존재하는데, 호출을 할 수 없다는 것은 직관적이지 않습니다. 따라서 Math에 있는 주석과 같이 주석을 달아주면 좋을 것입니다.
마지막으로 의도하지는 않았지만, 상속을 불가능하게 하는 효과도 얻을 수 있습니다.
모든 생성자는 명시적이든 묵시적이든 상위 클래스의 생성자를 호출하게 되는데, 생성자를 private로 선언했기 때문에 하위 클래스가 상위 클래스 생성자에 접근할 수 없습니다.
Ref : 이펙티브 자바 Effective Java 3/E
'Language > Java' 카테고리의 다른 글
[Java] Item 6 : 불필요한 객체 생성을 피하라 (1) | 2022.10.14 |
---|---|
[Java] Item 5 : 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (1) | 2022.10.13 |
[Java] Item 3 : private 생성자나 열거 타입으로 싱글톤임을 보증하라 (0) | 2022.10.10 |
[Java] Item 2 : 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2022.10.09 |
[Java] Item 1 : 생성자 대신 정적 팩토리 메서드를 고려하라 (1) | 2022.10.09 |
- Total
- Today
- Yesterday
- Effective Java
- algorithm
- Operating System
- ARP
- spring
- cs
- network
- GORM
- soft delete
- java
- effective
- go
- paging
- mmu
- Database
- fiber
- 공지
- OS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |