예외 처리 방법? 기본적인 처리 구조
예외 처리를 위해서는 try-catch 구문을 이용한다. 다음 코드를 보면 catch의 연속을 볼 수 있다.
try-catch
Multicatch block
throw, throws
finally
try-with-resource
Custom Exceptions
예외 처리 비용?
좀 신선한 내용을 봐서 다시한번 정리해본다. 보통의 예외처리는 비용이 비싸다. 이유는 Throwable 생성자의 fillInStackTrace()메서드가 주 원인이라고 한다. 메서드가 하는 일은 예외가 발생한 메서드의 Stack Trace를 모두 출력해주기 때문이다(StackTrace란 Application이 실행된 시점부터 현재 실행 위치까지의 메서드 호출 목록이다). 커스텀 예외에서 이 메서드를 오버라이딩해서 스택 트레이스를 최소화 해줄 수 있다고 한다.
@Override
public synchronized Throwable fillInStackTrace() { // 이런식으로
return this;
}
Java
복사
내 생각은 나쁘지 않은 방식인 것 같다. Stream에서 커스텀한 메서드를 체이닝하여 사용할때 좋을 수 있을 것 같다. 이유는 어쨋건 Stream을 사용하면 여러 단계를 거치는데 이를 좀 안전하고 명확하게 위치를 파악할 수 있기때문이라고 정리할 수 있을 것 같다. 아래의 코드를 보면 유효하다고 할 수 있을 지도? (예시로 만든거라 좀 이상할 수 있다.) 서버 입장에서는 예외가 길어지는 상황이면 성능에 저하가 올 수 있다. 하지만 이렇게 명확하게 알 수 있는 메서드에서 만약 예외가 난다면 나쁘지 않을 수 있을 것 같다. 물론 저렇게 사용하는 상황은 없겠지만…
public class Test {
public static void main(String[] args) {
int i = intToString("ABCD.EFG");
System.out.println(i);
}
/**
* ABCDEFG -> 1,2,3,4,5 배열을 만들어 합쳐주는 숫자로
* 만약 특수 문자면 예외를 던짐 -> SpecialToIntFormatException 발생
*
* 일반적인 상황 1개
* fillInStackTrace() 를 재정의한 상황 하나
*/
public static int intToString(String str){
return Arrays.stream(str.split(""))
.mapToInt(value -> value.charAt(0))
.mapToObj(operand -> {
Test.valid(operand);
return operand;
})
.collect(Collectors.summingInt(Integer::intValue));
}
public static void valid(int val){
if (val < 65 || val > 90){
throw new SpecialToIntFormatException("반환할 수 없습니다.");
}
}
}
class SpecialToIntFormatException extends RuntimeException{
public SpecialToIntFormatException(String message) {
super(message);
}
}
CONSOLE RESULT
Exception in thread "main" queiz.SpecialToIntFormatException: 반환할 수 없습니다.
at queiz.Test.valid(Test.java:35)
at queiz.Test.lambda$intToString$1(Test.java:28)
at java.base/java.util.stream.IntPipeline$1$1.accept(IntPipeline.java:180)
at java.base/java.util.stream.ReferencePipeline$4$1.accept(ReferencePipeline.java:212)
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at queiz.Test.intToString(Test.java:31)
at queiz.Test.main(Test.java:12)
Java
복사
not override
public class Test {
public static void main(String[] args) {
int i = intToString("ABCD.EFG");
System.out.println(i);
}
/**
* ABCDEFG -> 1,2,3,4,5 배열을 만들어 합쳐주는 숫자로
* 만약 특수 문자면 예외를 던짐 -> SpecialToIntFormatException 발생
*
* 일반적인 상황 1개
* fillInStackTrace() 를 재정의한 상황 하나
*/
public static int intToString(String str){
return Arrays.stream(str.split(""))
.mapToInt(value -> value.charAt(0))
.mapToObj(operand -> {
Test.valid(operand);
return operand;
})
.collect(Collectors.summingInt(Integer::intValue));
}
public static void valid(int val){
if (val < 65 || val > 90){
throw new SpecialToIntFormatException("반환할 수 없습니다.");
}
}
}
class SpecialToIntFormatException extends RuntimeException{
public SpecialToIntFormatException(String message) {
super(message);
}
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
CONSOLE RESULT
Exception in thread "main" queiz.SpecialToIntFormatException: 반환할 수 없습니다.
Java
복사