1. 예외 처리는 어떻게 해야 할까?
1.1. try-catch
<java />
try {
// 예외 발생할 일이 없는 로직 - 1
// 예외가 발생할 수도 있는 로직
// 예외 발생할 일이 없는 로직 - 2 : 예외 터지면 실행 X
} catch(예외 클래스 e) {
}
Q. exception이 여러 개인 경우 어떻게 함?
<java />
public class RoomService {
@Autowired
RoomRepository roomRepository;
public Room getRoom(int id) {
try{
return roomRepository.getRoom(id);
} catch (NoSuchElementException e){
return new NullRoom();
} catch (NullPointerException e) {
}...
}
}
구체적인 exception이 위로 오도록 코드를 작성.
범위가 넓은 exception을 먼저 쓰면 어떤 예외인지 명확히 알기 어렵기 때문이다.
1.2. throw
개발자가 임의로 발생시키는 예외 = 자바 입장에서는 예외가 아니다
<java />
public Room getRoom(int id){
Room room = roomTable.get(id);
try {
if(room!=null)
return roomTable.get(id);
else
throw new NoSuchElementException("no room");
}catch (NoSuchElementException e){
return new NullRoom();
}
}
null일때 그냥 new Room()을 반환하건 리팩토링 관점에서 좋지않다.
따라서 Null 객체를 만들어서 반환한다!
1.3. throws
예외를 발생시킨다. 다만, 메서드 내에서 예외처리를 하지 않고 해당 메서드를 사용한 곳에서 예외 처리를 하도록 예외를 위로 던지는 것이다. 예외를 전가하는 것.
다만, 아래 코드를 보면 throws를 사용하지 않았는데, 레포지토리에서 발생한 예외를 서비스단에서 잡고있다. 어떻게 된거지?
<java />
public class RoomRepository {
Map<Integer, Room> room_table = new HashMap<>();
public Room getRoom(int id) {
Room foundRoom = room_table.get(id);
if (foundRoom != null) {
return foundRoom;
} else {
throw new NoSuchElementException("no room with id " + id);
}
}
}
public class RoomService {
@Autowired
RoomRepository roomRepository;
public Room getRoom(int id) {
try{
return roomRepository.getRoom(id);
} catch (NoSuchElementException e){
e.printStackTrace();
return new NullRoom(); // 예외 처리를 서비스에 함
}
}
}
NoSuchElementException 은 Unchecked Exception이기 때문이다.
Checked Exception | Unchecked Exception | |
처리여부 | 반드시 예외를 처리 해야함 | 예외처리를 강제하지 않음 |
확인시점 | 컴파일 시점 | 런타임 시점 |
- Checked Exception은 throws 안해주면 컴파일 에러가 난다. IOException 같이, 컴파일 시점이기 때문에, 아직 어떤 클래스들끼리 호출하는지 흐름을 모른다.
- Unchecked exception은 thorws를 하지 않아도 에러가 나지 않음. NoSuchElementException 같이 런타임 시점이기 때문에, 누가 날 호출했는지 알고 있다. 따라서 throws를 사용하지 않아도, 호출 흐름상 어딘가에서 catch 해주면 된다.
Q. 이러면 왜 ,throws를 쓰지? 어차피 알아서 잡아주는데
명시적으로 표현해주기 위해서 사용한다.
2. 예외처리는 어디서 하는거죠?
- 예외가 발생 된 메서드에서 처리
- 호출한 메서드에서 처리
- 전역으로 처리
결론만 말하자면, 사용자 정의 예외 클래스를 만들고, 서비스단에서 예외를 만들어 던진다.
다만, 날아온 예외 객체들을 처리하는 로직은 컨트롤러단에서 수행한다.
'JAVA' 카테고리의 다른 글
내가 자바를 선택한 이유 (0) | 2024.07.10 |
---|---|
자바란 다형성이다. (0) | 2024.07.05 |
상속에 관하여 (0) | 2024.07.04 |
오버로딩(Overloading) vs 오버라이딩(Overriding) (0) | 2023.07.19 |