Skip to content

Commit 844aebd

Browse files
authored
아이템 25: 톱레벨 클래스는 한 파일에 하나만 담으라 (#113)
1 parent 1665405 commit 844aebd

4 files changed

+124
-0
lines changed

04장/아이템_25/compile_error.png

37.4 KB
Loading

04장/아이템_25/pancake.png

69.1 KB
Loading

04장/아이템_25/potpie.png

68.7 KB
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# 톱레벨 클래스는 한 파일에 하나만 담으라
2+
3+
## 요약
4+
5+
소스 파일 하나에 톱레벨 클래스를 여러 개 선언하더라도 자바 컴파일러는 불평하지 않는다.
6+
하지만 심각한 문제를 일으키니 하면 안된다.
7+
8+
9+
## 톱레벨 클래스란?
10+
Apple의 공식 문서에 따르면 톱-레벨의 정의는 다음과 같다.
11+
12+
Any executable statement not written within a function body,
13+
within a class, or otherwise encapsulated is considered top-level.
14+
15+
함수, 클래스 또는 다른 무언가로 감싸지지 않은 모든 구문은 톱-레벨로 간주된다.
16+
17+
즉, 톱레벨 클래스란 중첩 클래스가 아닌 것을 말한다.
18+
19+
## 코드 구성
20+
``` java
21+
// Main.java
22+
public class Main {
23+
24+
public static void main(String[] args) {
25+
System.out.println(Utensil.NAME + Dessert.NAME);
26+
}
27+
}
28+
```
29+
``` java
30+
// Utensil.java
31+
class Utensil {
32+
static final String NAME = "pan";
33+
}
34+
35+
class Dessert {
36+
static final String NAME = "cake";
37+
}
38+
```
39+
``` java
40+
// Dessert.java
41+
class Utensil {
42+
static final String NAME = "pot";
43+
}
44+
45+
class Dessert {
46+
static final String NAME = "pie";
47+
}
48+
```
49+
50+
## 문제 발생
51+
52+
### 컴파일 에러
53+
54+
`javac Main.java Dessert.java`
55+
56+
![](compile_error.png)
57+
58+
컴파일 에러가 나도 각 클래스를 중복해서 정의했다고 알려준다.
59+
60+
그 이유는 컴파일러는 다음과 같은 순서로 작동했기 때문이다.
61+
62+
1. 먼저 `Main.java` 컴파일
63+
2. 그 안에서 `System.out.println(Utensil.NAME + Dessert.NAME);` 구문을 만나기 때문에 `Utensil.java`를 컴파일
64+
3. 2번째 인수로 넘어온 `Dessert.java`을 컴파일 하려고 할 때 같은 클래스가 이미 정의되어 있는 것을 알게된다.
65+
66+
<br>
67+
68+
### Pancake 출력
69+
70+
`javac Main.java or javac Main.java Utensil.java`
71+
72+
![](pancake.png)
73+
74+
<br>
75+
76+
### Potpie 출력
77+
`javac Dessert.java Main.java`
78+
79+
![](potpie.png)
80+
81+
82+
## 해결책
83+
84+
### 톱레벨 클래스들을 서로 다른 소스 파일로 분리
85+
86+
``` java
87+
// Utensil.java
88+
public class Utensil {
89+
static final String NAME = "pan";
90+
}
91+
```
92+
``` java
93+
// Dessert.java
94+
public class Dessert {
95+
static final String NAME = "cake";
96+
}
97+
```
98+
99+
100+
### 톱레벨 클래스를 굳이 한 파일에 담고 싶을 때
101+
[맴버 클래스는 되도록 static으로 만들어라(아이템 24) By 연로그](https://github.com/woowacourse-study/2022-effective-java/blob/main/04%EC%9E%A5/%EC%95%84%EC%9D%B4%ED%85%9C_24/%EB%A9%A4%EB%B2%84%20%ED%81%B4%EB%9E%98%EC%8A%A4%EB%8A%94%20%EB%90%98%EB%8F%84%EB%A1%9D%20static%EC%9C%BC%EB%A1%9C%20%EB%A7%8C%EB%93%A4%EC%96%B4%EB%9D%BC.md)
102+
103+
``` java
104+
public class Main {
105+
106+
public static void main(String[] args) {
107+
System.out.println(Utensil.NAME + Dessert.NAME);
108+
}
109+
110+
private static class Utensil{
111+
static final String NAME = "pan";
112+
}
113+
114+
private static class Dessert{
115+
static final String NAME = "caks";
116+
}
117+
}
118+
```
119+
120+
121+
## 결론
122+
- 한 소스 파일안에 톱레벨 클래스를 하나만 만들자.
123+
- 사실 여러 톱레벨 클래스를 만들어도 이점이 없다.
124+
- 터미널을 통해서 javac 명령어를 이용하지 않으면 인텔리제이는 어떤 순서든 컴파일을 해주지 않는다.

0 commit comments

Comments
 (0)