diff --git "a/Ch04/item25/\355\206\261\353\240\210\353\262\250_\355\201\264\353\236\230\354\212\244\353\212\224_\355\225\234_\355\214\214\354\235\274\354\227\220_\355\225\230\353\202\230\353\247\214_\353\213\264\354\234\274\353\235\274.md" "b/Ch04/item25/\355\206\261\353\240\210\353\262\250_\355\201\264\353\236\230\354\212\244\353\212\224_\355\225\234_\355\214\214\354\235\274\354\227\220_\355\225\230\353\202\230\353\247\214_\353\213\264\354\234\274\353\235\274.md"
new file mode 100644
index 0000000..41303d0
--- /dev/null
+++ "b/Ch04/item25/\355\206\261\353\240\210\353\262\250_\355\201\264\353\236\230\354\212\244\353\212\224_\355\225\234_\355\214\214\354\235\274\354\227\220_\355\225\230\353\202\230\353\247\214_\353\213\264\354\234\274\353\235\274.md"
@@ -0,0 +1,91 @@
+# Item. 25 톱레벨 클래스는 한 파일에 하나만 담으라
+
+> 소스 파일 하나에는 반드시 톱레벨 클래스(혹은 톱레벨 인터페이스)를 하나만 담자
+> 이 규칙만 따른다면 컴파일러가 한 클래스에 대한 정의를 여러 개 만들어 내는 일은 사라진다.
+> 소스 파일을 어떤 순서로 컴파일하든 바이너리 파일이나 프로그램의 동작이 사라지지 않는다.
+
+---
+
+### 톱레벨 클래스란?
+
+- 소스 파일의 가장 바깥에 선언된 클래스를 말한다.
+- 중첩 클래스가 아닌 클래스를 말한다.
+
+
+
+### 예시 (따라 하지 말 것!)
+
+```java
+# Song.java
+class Genre {
+ static final String NAME = "POP";
+}
+
+class Song {
+ static final String NAME = "SONG";
+}
+```
+
+```java
+# Genre.java
+Genre.java
+class Genre {
+ static final String NAME = "K-POP";
+}
+
+class Song {
+ static final String NAME = "SONG";
+}
+```
+
+```java
+# main.java
+# 컴파일 에러 발생
+public class Test {
+ public static void main(String[] args) {
+ System.out.println(Genre.NAME + Song.NAME);
+ }
+}
+```
+
+
+
+### 해결 방법
+
+- 여러 톱레벨 클래스를 한 파일에 담고 싶다면 정적 멤버 클래스를 사용하는 방법이 있다.
+
+```java
+public class AB {
+ private static class A {
+
+ }
+
+ private static class B {
+
+ }
+}
+```
+
+
+
+---
+
+### Appendix
+
+**컴파일러의 동작:**
+
+- 소스 코드를 전체적으로 분석하여 중간 코드(Intermediate code) 또는 목적 코드(Object code)를 생성하는 과정이다.
+- 전체 소스 코드를 한 번에 번역하므로 실행 속도가 빠르다.
+- 번역된 결과물은 CPU가 직접 실행할 수 있는 기계어로 변환된다.
+
+**인터프리터의 동작:**
+
+- 소스 코드를 한 줄씩 읽어들이고, 해당 코드를 즉시 실행하는 과정이다.
+- 소스 코드를 한 줄씩 해석하고 실행하기 때문에 번역과 실행이 번갈아가면서 이루어진다.
+- 실행 속도가 상대적으로 느리지만, 개발 과정에서 수정 및 디버깅이 용이하다.
+
+**자바의 빌드 과정:**
+
+- 자바의 빌드 과정은 컴파일과 실행의 과정이 섞여 있음
+- 컴파일 단계에서 소스 코드를 중간 형태인 바이트 코드로 변환하고, 실행 단계에서 JVM을 통해 해당 바이트 코드를 인터프리터로 - 해석하여 실행하는 방식
+- 이러한 방식으로 자바 언어는 운영체제의 종류와 상관없이 동일한 바이트 코드를 실행하여 플랫폼 호환성을 제공
diff --git "a/Ch06/item38/\355\231\225\354\236\245\355\225\240_\354\210\230_\354\236\210\353\212\224_\354\227\264\352\261\260_\355\203\200\354\236\205\354\235\264_\355\225\204\354\232\224\355\225\230\353\251\264_\354\235\270\355\204\260\355\216\230\354\235\264\354\212\244\353\245\274_\354\202\254\354\232\251\355\225\230\353\235\274.md" "b/Ch06/item38/\355\231\225\354\236\245\355\225\240_\354\210\230_\354\236\210\353\212\224_\354\227\264\352\261\260_\355\203\200\354\236\205\354\235\264_\355\225\204\354\232\224\355\225\230\353\251\264_\354\235\270\355\204\260\355\216\230\354\235\264\354\212\244\353\245\274_\354\202\254\354\232\251\355\225\230\353\235\274.md"
new file mode 100644
index 0000000..a36ed5c
--- /dev/null
+++ "b/Ch06/item38/\355\231\225\354\236\245\355\225\240_\354\210\230_\354\236\210\353\212\224_\354\227\264\352\261\260_\355\203\200\354\236\205\354\235\264_\355\225\204\354\232\224\355\225\230\353\251\264_\354\235\270\355\204\260\355\216\230\354\235\264\354\212\244\353\245\274_\354\202\254\354\232\251\355\225\230\353\235\274.md"
@@ -0,0 +1,173 @@
+# Item 38. 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라
+
+- 열거타입 자체는 확장할 수 없지만, `인터페이스와 그 인터페이스를 구현하는 기본 열거 타입을 함께 사용해 같은 효과를 낼 수 있다.`
+- 이를 통해 클라이언트는 이 인터페이스를 구현해 자신만의 열거 타입(혹은 다른 타입)을 만들 수 있다.
+- API가 (기본 열거 타입을 직접 명시하지 않고) 인터페이스 기반으로 작성되었다면 기본 열거 타입의 인스턴스가 쓰이는 모든 곳을 새로 확장한 열거 타입의 인스턴스로 대체해 사용할 수 있다.
+
+---
+
+### 타입 안전 열거 타입
+
+```java
+public final class Direction {
+
+ public static final Direction NORTH = new Direction("N");
+ public static final Direction SOUTH = new Direction("S");
+ public static final Direction EAST = new Direction("E");
+ public static final Direction WEST = new Direction("W");
+
+ private Direction() {
+ ...
+ }
+}
+```
+
+- jdk1.5 이전에 enum이 없을 때 사용하던 방식
+
+
+
+### 열거 타입
+
+```java
+enum Direction {
+ NORTH, SOUTH, EAST, WEST;
+}
+```
+
+- `열거 타입은 거의 모든 상황에서 타입 안전 열거 패턴(typesafe enum pattern) 보다 우수`하다.
+- 단, 예외가 하나 있으니, 타입 안전 열거 패턴은 확장할 수 있으나 `열거 타입은 확장할 수 없다`.
+
+- `연산 코드(operation code)`에서 이따금 API가 제공하는 `기본 연산 외 사용자 확장 연산을 추가할 수 있도록 열어줘야 할 때`외에는 대부분의 상황에서 열거 타입을 확장하는 것은 좋지 않은 생각이다.
+ - 열거 타입을 확장하면, 확장한 타입의 원소는 기반 타입의 원소로 취금하지만 그 반대는 성립하지 않을 수 있다.
+ - 열거 타입을 확장하면 기반 타입과 확장 타입들의 원소 모두를 순회할 방법도 마땅하지 않다.
+ - 대부분의 상황에서 enum을 확장하는 것은 좋지 않다.
+- 열거 타입을 확장하려면 `열거 타입이 임의의 인터페이스를 구현할 수 있다는 사실을 이용`하면 된다.
+- `연산 코드용 인터페이스를 정의`하고 `열거 타입이 이 인터페이스를 구현`하게 하면 된다. 이 때 `열거 타입이 그 인터페이스의 표준 구현체 역할`을 한다.
+
+다음은 Operation 타입을 확장할 수 있게 만든 코드이다.
+
+**인터페이스를 이용해 확장 가능 열거 타입을 흉내 낸 코드**
+
+```java
+public interface Operation {
+ double apply(double x, double y);
+}
+```
+
+```java
+public enum BasicOperation implements Operation {
+ PLUS("+") {
+ public double apply(double x, double y) { return x + y; }
+ },
+ MINUS("-") {
+ public double apply(double x, double y) { return x - y; }
+ },
+ TIMES("*") {
+ public double apply(double x, double y) { return x * y; }
+ },
+ DIVIDE("/") {
+ public double apply(double x, double y) { return x / y; }
+ };
+
+ private final String symbol;
+
+ BasicOperation(String symbol) {
+ this.symbol = symbol;
+ }
+
+ @Override public String toString() {
+ return symbol;
+ }
+}
+```
+
+- 열거 타입인 BasicOperation은 확장할 수 없지만 인터페이스인 Operation은 확장할 수 있고, 이 인터페이스를 연산의 타입으로 사용하면 된다.
+
+- 예를 들어 앞의 연산 타입을 확장해 지수 연산(EXP)와 나머지 연산(REMAINDER)을 추가해보자. 이를 위해 우리가 할 일은 Operation 인터페이스를 구현한 열거 타입을 작성하는 것 뿐이다.
+
+**확장 가능 열거 타입**
+
+```java
+public enum ExtendedOperation implements Operation {
+ EXP("^") {
+ public double apply(double x, double y) {
+ return Math.pow(x, y);
+ }
+ },
+ REMAINDER("%") {
+ public double apply(double x, double y) {
+ return x % y;
+ }
+ };
+ private final String symbol;
+ ExtendedOperation(String symbol) {
+ this.symbol = symbol;
+ }
+ @Override public String toString() {
+ return symbol;
+ }
+}
+```
+
+- 새로 작성한 연산은 기존 연산을 쓰던 곳이면 어디든 쓸 수 있다.
+- Operation 인터페이스를 사용하도록 작성되어 있기만 하면 된다.
+
+개별 인스턴스 수준에서 뿐 아니라 타입 수준에서도, 기본 열거 타입 대신 확장된 열거 타입을 넘겨 확장된 열거 타입의 원소 모두를 사용하게 할 수도 있다.
+
+### 첫번째 대안) ExtendedOperation의 모든 원소 테스트하기
+
+```java
+public static void main(String[] args) {
+ double x = Double.parseDouble(args[0]);
+ double y = Double.parseDouble(args[1]);
+ test(ExtendedOperation.class, x, y);
+}
+private static & Operation> void test(
+ Class opEnumType, double x, double y) {
+ for (Operation op : opEnumType.getEnumConstants())
+ System.out.printf("%f %s %f = %f%n",
+ x, op, y, op.apply(x, y));
+}
+```
+
+- main 메서드는 test 메서드에 ExtendedOperation의 class 리터럴을 넘겨 확장된 연산들이 무엇인지 알려준다. 여기서 class 리터럴은 한정적 타입 토큰 역할을 한다.
+
+- opEnumType 매개변수의 선언(` & Operation> Class `)은 솔직히 복잡한데, `Class 객체가 열거 타입인 동시에 Oepration의 하위 타입이어야 한다`는 뜻이다.
+
+- 열거 타입이어야 원소를 순회할 수 있고, Operation이어야 원소가 뜻하는 연산을 수행할 수 있기 때문이다.
+
+### 두번쨰 대안) Class 객체 대신 한정적 와일드카드 타입인 Collection extends Operation>을 넘기는 방법
+
+```java
+public static void main(String[] args) {
+ double x = Double.parseDouble(args[0]);
+ double y = Double.parseDouble(args[1]);
+ test(Arrays.asList(ExtendedOperation.values()), x, y);
+}
+private static void test(Collection extends Operation> opSet,
+ double x, double y) {
+ for (Operation op : opSet)
+ System.out.printf("%f %s %f = %f%n",
+ x, op, y, op.apply(x, y));
+}
+```
+
+- 두번째 코드는 그나마 덜 복잡하고 여러 구현 타입의 연산을 조합해 호출할 수 있게 되었다.
+- 반면, 특정 연산에서는 EnumSet과 EnumMap을 사용하지 못한다.
+
+두 대안 프로그램 모두 명령줄 인수로 4와 2를 넣어 실행하면 다음 결과를 출력한다.
+
+```
+4.000000 ^ 2.000000 = 16.000000
+4.000000 % 2.000000 = 0.000000
+```
+
+---
+
+### 열거 타입에서 인터페이스를 이용해 확장 하는 경우 사소한 문제점
+
+- 인터페이스를 이용해 확장 가능한 열거 타입을 흉내 내는 방식에는 `열거 타입끼리 구현을 상속할 수 없다`는 사소한 문제점이 있다.
+
+- 아무 상태에도 의존하지 않는 경우에는 디폴트 구현을 이용해 인터페이스에 추가하는 방법이 있다. 반면 Operation 예는 연산 기호를 저장하고 찾는 로직이 BasicOperation과 ExtendedOepration 모두에 들어가야만 한다.
+
+- 이 경우에는 중복량이 적으니 문제되진 않지만, 공유하는 기능이 많다면 그 부분을 별도의 도우미 클래스나 정적 도우미 메서드로 분리하는 방식으로 코드 중복을 없앨 수 있을 것이다.
diff --git "a/Ch08/item50/\354\240\201\354\213\234\354\227\220_\353\260\251\354\226\264\354\240\201_\353\263\265\354\202\254\353\263\270\354\235\204_\353\247\214\353\223\244\353\235\274.md" "b/Ch08/item50/\354\240\201\354\213\234\354\227\220_\353\260\251\354\226\264\354\240\201_\353\263\265\354\202\254\353\263\270\354\235\204_\353\247\214\353\223\244\353\235\274.md"
new file mode 100644
index 0000000..6b8de15
--- /dev/null
+++ "b/Ch08/item50/\354\240\201\354\213\234\354\227\220_\353\260\251\354\226\264\354\240\201_\353\263\265\354\202\254\353\263\270\354\235\204_\353\247\214\353\223\244\353\235\274.md"
@@ -0,0 +1,102 @@
+# Item 50. 적시에 방어적 복사본을 만들라
+
+### 방어적으로 프로그래밍하기
+
+- 아무리 자바라고 해도 다른 클래스로부터의 침범을 아무런 노력없이 막을 수 있는 것은 아님
+- 악의적인 의도를 가진 사람들이 시스템의 보안을 뚫으려는 시도가 늘고 있음
+- 평범한 프로그래머도 순전히 실수로 클래스를 오작동하게 만들 수 있음
+
+**클라이언트가 \*불변식을 깨뜨리려 혈안이 되어 있다고 가정하고 방어적으로 프로그래밍 해야 함**
+
+\*`불변식`이란 프로그래밍에서 특정 조건이 항상 참이라는 것을 보장하는 성질이다. 이를 통해 코드의 안정성과 예측 가능성을 높일 수 있다.
+
+- 예시 1: 배열의 크기가 한 번 정해지면 변경되지 않도록 하여, 배열의 크기를 초과하는 인덱스로의 접근을 방지하는 것이다.
+- 예시 2: final 키워드를 사용하여 상수를 선언함으로써, 그 값을 다른 것으로 변경하는 것을 방지하는 것이다.
+
+방어적 프로그래밍의 관점에서 불변식을 지키는 것은 중요하다.
+
+클라이언트가 불변식을 깨뜨리려 할 경우, 이를 감지하고 예외를 발생시키는 것이 좋다.
+
+
+
+### 예시 1
+
+```java
+public final class Period {
+ private final Date start;
+ private final Date end;
+
+ public Period(Date strart, Date end) {
+ if (start.compareTo(end) > 0)
+ throw new IllegalArgumentException(
+ start + "가 " + end + "보다 늦다.");
+ this.start = start;
+ this.end = end;
+ }
+
+ public Date start() {
+ return start;
+ }
+
+ public Date end() {
+ return end;
+ }
+
+}
+```
+
+```java
+Date start = new Date();
+Date end = new Date();
+Period p = new Period(start, end);
+end.setYear(78);
+```
+
+이렇게 바로 end의 내부를 불변식을 깨트릴 수 있다고 한다.
+
+_해당 Date 에 대해서 지금의 자바는 어떻게 해야할까?_
+
+- Date 대신 불변인 Instant를 사용하면 된다.
+- Java8 이상부터는 LocalDateTime이나 ZonedDateTime을 사용해도 된다.
+- Date는 낡은 API이니 새로운 코드를 작성할 때는 더이상 사용하면 안된다.
+- 이러한 Date 말고도 다른 상황에서도 불변식은 깨질 수 있다고 본다.
+
+
+
+### 예시 2
+
+```java
+Date start = new Date();
+Date end = new Date();
+Period p = new Period(start, end);
+p.end().setYear(78)
+```
+
+Period에 대한 인스턴스 공격을 이런식으로도 깨트릴 수 있다. 하지만 막는 것은 간단하다.
+
+```java
+public Date start() {
+ return new Date(start.getTime());
+}
+public Date end() {
+ return new Date(end.getTime());
+}
+```
+
+바로 위와 같이 가변 필드의 방어적 복사본을 반환하면 된다.
+
+- 아무리 악의적인 혹은 부주의한 프로그래머라도 시작 시간이 종료 시간보다 나중일 수 없다는 불변식을 위배할 방법이 없다.
+- Period 자신 말고는 가변 필드에 접근할 방법이 없다.
+- 모든 필드가 객체 안에 완벽하게 캡슐화된다.
+- 해당 방법을 사용할 때는 생성자와 달리 접근 메서드에 대해 복사본을 만드는 것이기 때문에 clone을 사용해도 된다.
+ - Period가 가지고 있는 Date 객체가 java.util.Date 임이 확실하기 때문
+
+단, 인스턴스를 복사하는 데는 일반적으로 생성자나 정적 팩터리를 쓰는 것이 좋다.
+
+
+
+### 정리
+
+- 클래스가 클라이언트로부터 받는 혹은 클라이언트로 반환하는 구성요소가 가변이라면 그 요소는 반드시 방어적으로 복사해야 함
+
+- 복사 비용이 너무 크거나, 클라이언트가 그 요소를 잘못 수정할 일이 없음을 신뢰한다면 방어적 복사를 수행하는 대신 구성요소를 수정했을 때의 책임이 클라이언트에 있음을 문서에 명시해야 함