우선, 일반적으로 회복이 불가능한 문제입니다.
이에 반해, Exception(예외)는 일반적으로 회복이 가능한 문제입니다.
회복이 가능하다는 것은 예외 발생을 인지하고 대응할 수 있음을 의미합니다.
예외의 종류
컴파일 에러
.java 파일을 .class 파일로 컴파일 하는 과정에서 발생하는 에러런타임 에러(Runtime Error)
- 우리가 주로 다루게 될 예외입니다.
- 문법적인 오류가 아닌 컴파일은 잘되었지만 “프로그램”이 실행도중 맞딱드리게 되는 예외입니다.
이렇게 크게 예외의 종류를 구분할 수 있고, 확인된 에러를 다시 한번 두가지로 분류를 할 수 있습니다.
Checked Exception ✅
Unchecked Exception ❌
우리가 예외를 어떻게 정의하고,
예외가 발생할 수 있음을 알리고,
사용자는 예외가 발생할 수 있음을 알고 핸들링하는지
위의 부분을 주의 깊게 봐야 합니다.
public class CustomException extends Exception{
public CustomException(String message){
super(message);
}
}
위 처럼 Exception을 커스텀하기 위해서는 Exception 클래스를 상속받아야하고, super() 키워드를 통해서 우리의 코드에서 입력되는 메세지에 대하서 throw 할 수 있게 해줘야 합니다.
public class OurClass{
private final boolean just = true;
// throws : method 이름 뒤에 붙어 이 method가 어떠한 예외사항을 던질 수 있는지 알려줍니다.
// throw : method 안에서 실제로 예외 객체를 던칠 때 사용합니다.
public void thisMethodIsDangerous()throws CustomException{
//logic<>
if(just){
throw new CustomException("Just is true.")
}
}
}
이렇게 위 코드 같이 구현할 수 있습니다. 여기서 throws 를 통해서 다양한 Exception을 받아 올 수 있습니다. 이러한 클래스를 main method 에서 사용하려고 할때 따로 flag 를 주지 않았기 때문에 실행이 되지 않습니다. 그렇기에 try~catch~finally 문을 사용하여 동작을 시킵니다.
OurClass ourClass = new OurClass();
try{
ourClass.thisMethodIsDangerous();
}catch(CustomException e){
System.out.println(e.getMessage());
}finally{
// 무조건 거쳐가는 단계
System.out.println("예외처리 완료 했습니다.");
}
Object→ Throwable Class
시작은 모든 객체의 원형인 Object 의 상속을 받아 시작합니다. Throwable 클래스에는 자식으로서 에러와 예외 클래스가 존재합니다. 이러한 클래스 들은 내부에서 IOError 클래스, RuntimeException 클래스와 같이 구분되어 처리됩니다.


Chained Excpetion
initCause() : 지정한 예외를 원인 예외로 등록하는 경우getCause() : 원인 예외를 반환하는 메서드타입 언어에서 “중복되거나 필요없는 코드를 줄여주는 것”입니다.
타입 안정성을 해치지 않습니다!
예시
// 1. 제네릭은 클래스 또는 메서드에 사용 가능합니다.
// <>안에 사용할 타입을 넣어주면 됩니다.
// 그래서 T를 타입변수라고 명명합니다.
// Generic class 를 원시 타입이라고 합니다.
public class Generic<T> {
// 2. 내부 필드에 대입됩니다.
private T t;
// 3. 리턴 타입도 입력 타입으로 바뀝니다.
public T get() {
return this.t;
}
public void set(T t) {
this.t = t;
}
public static void main(String[] args) {
// 4.생성 및 사용
Generic<String> stringGeneric = new Generic<>();
// 5. 출력
stringGeneric.set("Hello World");
String tValueTurnOutWithString = stringGeneric.get();
System.out.println(tValueTurnOutWithString);
}
}
다수의 타입을 가져올 수 있습니다.
public class Generic<T, U, E> {
public E multiTypeMethod(T t, U u) { ... }
}
Generic<Long, Integer, String> instance = new Generic();
instance.multiTypeMethod(longVal, intVal);
다형성 즉 상속과 타입의 관계는 그대로 적용됩니다.
와일드카드를 통해 제네릭의 제한을 구체적으로 정할 수 있습니다.
public class ParkingLot<T extends Car> { ... }
ParkingLot<BMW> bmwParkingLot = new ParkingLot();
ParkingLot<Iphone> iphoneParkingLot = new ParkingLog(); // error!