From e3e1ca594c4c9b3bdf32facfa1f07aefbdef70d7 Mon Sep 17 00:00:00 2001 From: bo-ram-bo-ram Date: Sun, 16 Jun 2024 23:55:18 +0900 Subject: [PATCH 1/3] create : item24 --- ...4_\353\247\214\353\223\244\353\235\274.md" | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 "boram/week7/\353\263\264\353\236\214-7\354\243\274\354\260\250-\354\225\204\354\235\264\355\205\23424_\353\251\244\353\262\204_\355\201\264\353\236\230\354\212\244\353\212\224_\353\220\230\353\217\204\353\241\235_static\354\234\274\353\241\234_\353\247\214\353\223\244\353\235\274.md" diff --git "a/boram/week7/\353\263\264\353\236\214-7\354\243\274\354\260\250-\354\225\204\354\235\264\355\205\23424_\353\251\244\353\262\204_\355\201\264\353\236\230\354\212\244\353\212\224_\353\220\230\353\217\204\353\241\235_static\354\234\274\353\241\234_\353\247\214\353\223\244\353\235\274.md" "b/boram/week7/\353\263\264\353\236\214-7\354\243\274\354\260\250-\354\225\204\354\235\264\355\205\23424_\353\251\244\353\262\204_\355\201\264\353\236\230\354\212\244\353\212\224_\353\220\230\353\217\204\353\241\235_static\354\234\274\353\241\234_\353\247\214\353\223\244\353\235\274.md" new file mode 100644 index 0000000..97bd812 --- /dev/null +++ "b/boram/week7/\353\263\264\353\236\214-7\354\243\274\354\260\250-\354\225\204\354\235\264\355\205\23424_\353\251\244\353\262\204_\355\201\264\353\236\230\354\212\244\353\212\224_\353\220\230\353\217\204\353\241\235_static\354\234\274\353\241\234_\353\247\214\353\223\244\353\235\274.md" @@ -0,0 +1,32 @@ +중첩 클래스(nested class)는 다른 클래스 안에 정의된 클래스를 말한다. +중첩 클래스는 자신을 감싼 바깥 클래스에서만 사용되어야 하며, 그 외의 쓰임새가 있다면 톱레벨 클래스로 만들어야 한다. +중첩 클래스는 크게 네 가지로 나뉜다: 정적 멤버 클래스, 비정적 멤버 클래스, 익명 클래스, 지역 클래스. +이 중 첫 번째를 제외한 나머지는 내부 클래스(inner class)에 해당한다. + +1. **정적 멤버 클래스 (static member class)**: + - 다른 클래스 안에 선언되며 바깥 클래스의 private 멤버에도 접근할 수 있다. + - 바깥 클래스와 독립적으로 존재할 수 있으며, 주로 바깥 클래스와 함께 사용할 때 유용한 public 도우미 클래스로 쓰인다. + +2. **비정적 멤버 클래스 (non-static member class)**: + - 바깥 클래스의 인스턴스와 암묵적으로 연결된다. + - 인스턴스 메서드에서 바깥 인스턴스의 메서드나 참조를 사용할 수 있다. + - 보통 바깥 클래스의 인스턴스 메서드에서 생성된다. + - 주로 어댑터를 정의할 때 사용된다. + +3. **익명 클래스 (anonymous class)**: + - 이름이 없고, 선언과 동시에 인스턴스가 만들어진다. + - 선언된 지점에서만 인스턴스를 생성할 수 있으며, 여러 인터페이스를 구현하거나 다른 클래스를 상속할 수 없다. + - 람다가 도입된 후에는 람다로 대체되는 경우가 많다. + +4. **지역 클래스 (local class)**: + - 지역변수를 선언할 수 있는 곳이면 어디든 선언할 수 있다. + - 이름이 있어 반복 사용할 수 있으며, 비정적 문맥에서만 바깥 인스턴스를 참조할 수 있다. + +중첩 클래스에서 바깥 인스턴스에 접근할 필요가 없다면 static으로 선언하는 것이 좋다. +static을 생략하면 바깥 인스턴스로의 숨은 참조가 생기고, 메모리와 시간이 소비된다. +공개된 클래스의 멤버 클래스는 정적이냐 비정적이냐에 따라 하위 호환성에 영향을 미친다. + +## 핵심정리 +중첩 클래스에는 네가지가 있으며, 각각의 쓰임이 다르다. 메스드 밖에서도 사용해야 하거나 메서드 안에 정의하기엔 너무 길다면 멤버 클래스로 만든다. +멤버 클래스의 인스턴스 각각이 바깥 인스턴스를 참조한다면 비정상적으로, 그렇지 않으면 정적으로 만들자. +중첩 클래스가 한 메서드 안에서만 쓰이면서 그 인스턴스를 생성하는 지점이 단 한 곳이라고 해당 타입으로 쓰기에 적합한 클래스나 인터페이스가 이미 있다면 익명 클래스로 만들고, 그렇지 않으면 지역 클래스로 만들자. \ No newline at end of file From 8b342b35b38773edaa1e80bcb91fd47ce6cba0db Mon Sep 17 00:00:00 2001 From: bo-ram-bo-ram Date: Sun, 16 Jun 2024 23:55:27 +0900 Subject: [PATCH 2/3] create : item 25 --- ...4_\353\213\264\354\234\274\353\235\274.md" | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 "boram/week7/\353\263\264\353\236\214-7\354\243\274\354\260\250-\354\225\204\354\235\264\355\205\23425_\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" diff --git "a/boram/week7/\353\263\264\353\236\214-7\354\243\274\354\260\250-\354\225\204\354\235\264\355\205\23425_\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/boram/week7/\353\263\264\353\236\214-7\354\243\274\354\260\250-\354\225\204\354\235\264\355\205\23425_\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..30613e2 --- /dev/null +++ "b/boram/week7/\353\263\264\353\236\214-7\354\243\274\354\260\250-\354\225\204\354\235\264\355\205\23425_\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,33 @@ +소스 파일 하나에 여러 개의 톱레벨 클래스를 선언하는 것은 자바 컴파일러가 허용하지만, 이는 득이 없고 심각한 위험을 초래할 수 있다. 이런 방식은 한 클래스를 여러 가지로 정의할 수 있으며, 컴파일 순서에 따라 다른 클래스를 사용할 수 있기 때문이다. + +예를 들어, `Main` 클래스가 두 개의 톱레벨 클래스 `Utensil`과 `Dessert`를 참조한다고 하자. 이 두 클래스가 `Utensil.java` 파일에 정의되어 있다면, `Main`을 실행하면 "pancake"를 출력할 것이다. 그런데 `Dessert.java` 파일에 같은 이름의 두 클래스를 정의하면, 컴파일 순서에 따라 출력이 달라질 수 있다. + +- `javac Main.java Dessert.java` 명령으로 컴파일하면 컴파일 오류가 발생하고, 중복 정의가 있다고 알려준다. +- `javac Main.java` 또는 `javac Main.java Utensil.java` 명령으로 컴파일하면 "pancake"를 출력한다. +- `javac Dessert.java Main.java` 명령으로 컴파일하면 "potpie"를 출력한다. + +이 문제는 간단히 톱레벨 클래스를 각기 다른 소스 파일로 분리하여 해결할 수 있다. 부차적인 클래스라면 정적 멤버 클래스로 만드는 것이 좋다. 이는 코드의 가독성을 높이고 접근 범위를 최소화할 수 있다. + +다음은 정적 멤버 클래스로 바꾼 예시이다: + +```java +public class Test { + public static void main(String[] args) { + System.out.println(Utensil.NAME + Dessert.NAME); + } + + private static class Utensil { + static final String NAME = "pan"; + } + + private static class Dessert { + static final String NAME = "cake"; + } +} +``` + +이와 같이 정적 멤버 클래스를 사용하면 코드가 더 명확하고 관리하기 쉬워진다. + +## 핵심정리 +소스 파일 하나에는 반드시 톱레벨 클래스를 하나만 담자. 이 규칙만 따른다면 컴파일러가 한 클래스에 대한 정의를 여러 개 만들어 내는 일은 사라진다. +소스 파일을 어떤 순서로 컴파일하든 바이너리 파일이나 프로그램의 동작이 달라지는 일은 결코 일어나지 않을 것이다. \ No newline at end of file From dc02a031c1178fcf1dad237c97b0486f527d69b9 Mon Sep 17 00:00:00 2001 From: bo-ram-bo-ram Date: Sun, 16 Jun 2024 23:55:41 +0900 Subject: [PATCH 3/3] create : item 26 --- ...0\354\247\200_\353\247\220\353\235\274.md" | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 "boram/week7/\353\263\264\353\236\214-7\354\243\274\354\260\250-\354\225\204\354\235\264\355\205\23426_\353\241\234_\355\203\200\354\236\205\354\235\200_\354\202\254\354\232\251\355\225\230\354\247\200_\353\247\220\353\235\274.md" diff --git "a/boram/week7/\353\263\264\353\236\214-7\354\243\274\354\260\250-\354\225\204\354\235\264\355\205\23426_\353\241\234_\355\203\200\354\236\205\354\235\200_\354\202\254\354\232\251\355\225\230\354\247\200_\353\247\220\353\235\274.md" "b/boram/week7/\353\263\264\353\236\214-7\354\243\274\354\260\250-\354\225\204\354\235\264\355\205\23426_\353\241\234_\355\203\200\354\236\205\354\235\200_\354\202\254\354\232\251\355\225\230\354\247\200_\353\247\220\353\235\274.md" new file mode 100644 index 0000000..ba61ee4 --- /dev/null +++ "b/boram/week7/\353\263\264\353\236\214-7\354\243\274\354\260\250-\354\225\204\354\235\264\355\205\23426_\353\241\234_\355\203\200\354\236\205\354\235\200_\354\202\254\354\232\251\355\225\230\354\247\200_\353\247\220\353\235\274.md" @@ -0,0 +1,67 @@ +## 제네릭 +제네릭(generic)은 자바 5부터 사용할 수 있으며, 제네릭을 사용하면 컬렉션이 담을 수 있는 타입을 컴파일러에 알려줘 형변환 오류를 방지하고, 더 안전하고 명확한 프로그램을 만들 수 있다. 제네릭 타입을 사용하면 컴파일러가 형변환 코드를 자동으로 추가해준다. + +## 주요 개념 +1. 제네릭 클래스와 인터페이스 + 타입 매개변수를 사용하는 클래스와 인터페이스를 말한다. + 예: List는 원소의 타입을 나타내는 타입 매개변수 E를 받는다. + +2. 매개변수화 타입: + + 제네릭 타입에 실제 타입 매개변수를 지정한 것을 말한다. + 예: List은 원소의 타입이 String인 리스트를 의미한다. + + 3. raw type: + 제네릭 타입에서 타입 매개변수를 전혀 사용하지 않은 것. + 예: List는 List의 로 타입이다. + 로 타입을 사용하면 타입 안전성과 표현력을 잃게 된다. + +## 제네릭의 사용 예시 + 1. 로 타입 사용 예 (사용하지 말 것): +```java + private final Collection stamps = ...; + stamps.add(new Coin(...)); // "unchecked call" 경고 발생 + for (Iterator i = stamps.iterator(); i.hasNext();) { +Stamp stamp = (Stamp) i.next(); // ClassCastException 발생 가능 + stamp.cancel(); +} + +``` + + 2. 매개변수화된 컬렉션 타입 사용 예: +```java + private final Collection stamps = ...; +``` + + 3. 비한정적 와일드카드 타입 사용 예: +```java + static int numElementsInCommon(Set s1, Set s2) { + int result = 0; + for (Object o1 : s1) { + if (s2.contains(o1)) result++; + } + return result; +} + +``` + +## 로 타입 사용을 피해야 하는 이유 +로 타입을 사용하면 타입 안전성을 잃게 되어 런타임 오류가 발생할 수 있다. +대신, 비한정적 와일드카드 타입을 사용하면 더 안전하게 코드를 작성할 수 있다. + +## 예외 사항 +1. class 리터럴: +- 제네릭 타입의 class 리터럴은 사용할 수 없다. +- 예: List.class, String[].class, int.class는 허용되지만 List.class, List.class는 허용되지 않는다. + +2. instanceof 연산자: +- 런타임에 제네릭 타입 정보가 지워지므로, instanceof 연산자는 비한정적 와일드카드 타입 이외의 매개변수화 타입에는 적용할 수 없다. +예: +```java + if (o instanceof Set) { // 로 타입 + Set s = (Set) o; // 와일드카드 타입 + } +``` + +## 핵심 정리 +raw type을 사용하면 런타입외 예외가 일어날 수 있으니 사용하면 안됟나. raw type은 제네릭이 도입되기 이전 코드와의 호환성을 위해 제공될 뿐이다. \ No newline at end of file