예외란?
예상된 결과 외의 다른 결과
원하는 것이 아니거나 의도치 않은 경우
💣 예외(오류)를 경험해보자

- 위코드를 실행하면 nullpointerexception 오류가 발생한다..펑..!💣
- 오류가 발생한 이유는 뭐고, 어디서 터진걸까?
id을 통해 찾은 결과가 null인데 .getName()을 적용하였기 nullpointerexception 아무것도 존재하지 않는다는 의미의 에러를 발생한다. (cf. 참조 자료형이기 때문에 null pointer 에러가 생김)
발생한 에러처리는 어디에서 해야할까?
첫번째 궁금증. 호출을 당한 곳에서 에러처리를 해야해?
아니지! 호출을 한 곳에서 에러처리를 해야되지!! 그게 매너아니겠어?!
먼저, if else를 걸어서 에러 처리를 해보자!
코드를 짜고보니깐 맘에 들지 않는 점ㅎ
- 중복 코드가 너무 많으니깐 아래 코드로 일단 고치자!

- null자체가 에러인데 이걸 반환해..? 좀 거슬리네!!
폭탄 돌리기하는 것도 아니구,, 이것도..내가 처리해야하는거 아닌가..?
그럼 null을 바로 반환하지말고 한겹 포장해서 보내자!
⚠️주의할 점 한쪽에 몰려서 에러를 처리하는 것보다 적당량을 나눠서 처리하는 것이 좋음
Optional의 등장 ‼️두둥‼️
- 장점: 언제든 npe가 터지지 않게 null을 한겹 포장해서 보내자! 받는 즉시 NPE가 터지는 걸 막을 수 있고, 받는 애는 까기 전까지는 에러가 터지지 않게 하기 위해! -> Optional class(java)
쉽게 말하자면, Optional: 포장지같은 용도로 null인지 아닌지 확인할 수 있도록 껍데기를 싸는 것이다!
Optional 메소드
- isPresent(): 안에 값이 있나 없나?
- get(): 안에 있는 값을 꺼내는 것
=> 이렇게 쓸거면,, 왜 return null 안쓰고 굳이 optional쓰지?
[안에 값이 없을 때]
-
orElse(기존에 있는 객체): 안에 값이 없을때, 기존에 있던 객체를 대입
-
orElseGet(새로운 객체를 생성해 달라고 요청하는 함수): 안에 값이 없을 때, 디폴트 값으로 새로운 객체를 대입(이거 가져가서 써~! )
-
orElseThrow(새로운 객체를 생성해 달라고 요청하는 함수): 안에 값이 없을 때, 예외 객체로 처리해줘~
⚠️주의⚠️
- get 사용금지
return null을 하기위해 존재하긴 하지만, null을 확인하고 넘어가는게 목적이기 때문에 지양하는 메소드이다. 대신 orElse throws orElse get을 쓰자!

Supplier? 예외 클래스를 받아서 처리? 함수가 반환하는 값을 쓰고 싶은데 근데 그 함수를 한번만 쓸거야, 함수로 따로 빼기에는 굳이? 매개변수로 함수가 들어가고, 함수의 반환값을 받아주는 타입이 supplier
orElseGet 내가 예외 말고 객체를 만들어줘!
orElseThrow 야 없다 내가 만들어둔 예외 터트려!
lambda? 내가 원하는 Exception 예외 클래스를 발생시키기 위해 사용
: new 예외 클래스를 생성시키는 문법으로 lambda를 간추려서 보낸 것
- ispresent 사용금지

우리가 짤 수 있는 코드를 Optional에게 전가한 것이기 때문
- 여기서 퀴즈~! field에 Optional을 쓰지 않은 이유는?
- 직렬화가 되지 않음-> 포장지를 어떻게 쌀거야...
- null을 대체하는데 null이 보통 클래스에서 어디에 위치할까? 뭐할때 등장 ? 꺼낼때만 등장
null을 타입으로 써본적은 없음 return null을 대체하거나 반환타입을 대체하려고 나온 것이기 때문에 field에서 사용하는 것은 고려하지 않았기 때문에 필드에서 사용하지 않음
- map lambda string 문법을 잘 사용하지 않음 없어도 구현이 가능하기 때문!
return null을 할 일이 언제일까? 없는 값 조회할때
아무것도 없네? null을 던졌다가는 객체를 줄 것이라고 생각할텐데 프로그램이 죽을텐데
결국 Optional은 프로그램의 안정성을 위해서 사용됨
cf. 영속성: 영원히 지속하는 것
jpa는 java persistant api 자바(객체)가 영원히 지속될 수 있도록 도와주는 api로 optional이 유명해진 이유이다!
예외처리 방법
- try catch (finally)
try{
}catch(예외 클래스 e객체){
}
- throw: 개발자가 임의로 발생시키는 예외
= 자바 입장에서는 예외가 아님.

Null을 보내기 좀 그러니깐, null을 받을 수 있는 room을 상속받아서 NullRoom을 return하자!
- throws: 예외가 터졌는데 내가 터트린게 아냐! 나를 부른 상위메소드에게 예외를 던지는 것 = 예외에 대한 책임을 전가
- unchecked: 런타임 시점 ex.NoSuchElementException
=> 호출 흐름상 어딘가에서 catch해주면 됨!
- checked: 컴파일 시점 ex.IOException
(아직 어떤 클래스끼리 호출하는지 "흐름" 모름 : A클래스와 B클래스연결(링킹)이 컴파일 이후 일어남 따라서 누가 처리를 해줄거라는 인지가 되지 않기 때문)
=> throws를 쓰지 않으면, 컴파일 에러!
Repository

Service

try-catch안쓰고 throws쓰는 이유는 "나 에러 발생시킨다!!"를 명시적으로 보여주기 위해
예외 클래스


위 표에서 잘못된 점⛔️
3번째줄: 자바예외 클래스에서는 roll-back을 해주지 않는다. (스프링은 가능)
JAVA 세상에서는 roll-back하지 않음, roll-back 함-> roll-back을 해야 함으로 변경해야 한다.
올바른 표 ✅

사용자 예외 클래스 생성하기
- NoSuchElementException을 상속받아 사용자 예외 클래스를 생성한다.

- 위는 자식(자신의) getMessage메소드를 사용하는 코드

- 위는 부모 getMessage메소드를 사용하는 코드

마무리~ 예외 클래스를 구체화하면 좋은 이유
- 에러를 잡기가 쉬워요!
= 추적하기가 쉽다.
- 어떤 에러인지 알 수 있어요!
= 의미를 가지게 할 수 있어요
=> 클래스명 구체화 가능