


Maven Repository: org.projectlombok » lombok » 1.18.32
예외 클래스 만들기

Menu에서 throw 처리해주기



## 1교시
### 제너릭
제네릭은 <> 꺾쇠 괄호 키워드를 사용하는데 이를 다이아몬드 연산자라고 한다
우리가 변수를 선언할때 변수의 타입을 지정해주듯이, 제네릭은 객체(Object)에 타입을 지정해주는 것이라고 보면 된다.
일반 메서드보다는 static 메서드에서 주로 사용
타입추론: 선언문을 보고 어떤 타입으로 인스턴스화 하는지는 생략가능
Box<String> box = new Box<>();
- T – Type
- E – Element
- K – Key
- N – Number
- V – Value
jdk 1.7 버전 이후부터, new 생성자 부분의 제네릭 타입을 생략할 수 있게 되었다. 제네릭 나름대로 타입 추론을 해서 생략 된 곳을 넣어주기 때문에 문제가 없는 것이다.
// 제네릭 타입 매개변수에 정수 타입을 할당
FruitBox<Integer> intBox = new FruitBox<>();
// 제네릭 타입 매개변수에 실수 타입을 할당
FruitBox<Double> intBox = new FruitBox<>();
// 제네릭 타입 매개변수에 문자열 타입을 할당
FruitBox<String> intBox = new FruitBox<>();
// 클래스도 넣어줄 수 있다. (Apple 클래스가 있다고 가정)
FruitBox<Apple> intBox = new FruitBox<Apple>();
<T> 부분에서 실행부에서 타입을 받아와 내부에서 T 타입으로 지정한 멤버들에게 전파하여 타입이 구체적으로 설정 이를 **구체화(Specialization)** 라고 한다.
### 제네릭 클래스
클래스 선언문 옆에 제네릭 타입 매개변수가 쓰이면, 이를 제네릭 클래스라고 한다.
### 제네릭 인터페이스
인터페이스에도 제네릭을 적용 할 수 있다. 단, 인터페이스를 implements 한 클래스에서도 오버라이딩한 메서드를 제네릭 타입에 맞춰서 똑같이 구현해 주어야 한다.
### 제네릭 메서드
메서드의 선언부에 <T> 가 선언된 메서드를 말한다.
```java
class FruitBox<T> {
// 클래스의 타입 파라미터를 받아와 사용하는 일반 메서드
public T addBox(T x, T y) {
// ...
}
// 독립적으로 타입 할당 운영되는 제네릭 메서드
public static <T> T addBoxStatic(T x, T y) {
// ...
}
}
위에서는 클래스의 제네릭 ~~<T>~~ 에서 설정된 타입을 받아와 반환 타입으로 사용할 뿐인 일반 메서드라면, 제네릭 메서드는 직접 메서드에 ~~<T>~~ 제네릭을 설정함으로서 동적으로 타입을 받아와 사용할 수 있는 **독립적으로 운용 가능한** 제네릭 메서드라고 이해하면 된다.\\
### 타입 한정 키워드 extends
기본적인 용법은 <T extends [제한타입]>
제네릭 <T> 에 extends 키워드를 붙여줌으로써, <T extends Number> 제네릭을 Number 클래스와 그 하위 타입(Integer, Double)들만 받도록 타입 파라미터 범위를 제한 한 것이다.
#### 와일드카드
#### 다중 타입 한정
만일 2개 이상의 타입을 동시에 상속(구현)한 경우로 타입 제한하고 싶다면, `&` 연산자를 이용하면 된다. 해당 인터페이스들을 동시에 구현한 클래스가 제네릭 타입의 대상이 되게 된다.
단, 자바에서는 다중 상속을 지원하지 않기 때문에 클래스로는 다중 extends는 불가능하고 오로지 인터페이스로만이 가능하다.
## 2교시
### 컬렉션
자료 구조(Data Structure) 종류의 형태들을 자바 클래스로 구현한 모음집
https://www.geeksforgeeks.org/collections-in-java-2/

package ch15.sec05.exam04;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
class Fruit2 {
String name;
int price;
Fruit2(String name, int price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return name + ", " + price;
}
}
public class ComparatorExample2 {
public static void main(String[] args) {
// ArrayList 생성
ArrayList<Fruit2> fruits = new ArrayList<>();
// 데이터 추가
fruits.add(new Fruit2("포도", 3000));
fruits.add(new Fruit2("수박", 10000));
fruits.add(new Fruit2("딸기", 6000));
// 가격을 기준으로 정렬
Collections.sort(fruits, new Comparator<Fruit2>() {
@Override
public int compare(Fruit2 f1, Fruit2 f2) {
return Integer.compare(f1.price, f2.price);
}
});
// 정렬된 데이터 출력
for (Fruit2 fruit : fruits) {
System.out.println(fruit);
}
}
}