❤️01_Java

#java #exception #CheckedException #UncheckedException #Runtime Exception #Error

roomname-dev 2023. 11. 14.
728x90
반응형

자바에서 프로그래밍을 하다보면 예외처리는 항상 불가결한 존재이다. 예외란 통상 "예기치 못한 예상하지 못한 일에 대해서 발생하는 것을 미리 예견하고 안전장치를 하는 것" 이라고 말을 합니다. 

 

자바에서 예외를 말할때 Error, Checked Exception , Runtime exception(unchecked exeption) 이렇게 이야기 할수 있다. 

 

📚Error 

자바 프로그램 밖에서 발생한 예외를 뜻하며 서버의 디스크 고장, 메인보드 이슈등 프로그램단 외 영역에서 발생하는 오류를 말합니다. 오류의 이름이 Error로 끝나는 케이스 입니다. Exception은 쓰레드에만 영향을 주지만 Error는 프로세스 전체

에 영향을 야기합니다. 

 

📀 Error 종류

⭐ LinkageError

- java.lang.LinkageError클래스를 사용하고 있는 패키지는 java.lang, java.lang.reflect등이 있다. 
- Linkage는 통상 java version을 변경해서 사용하지 못할때 발생하는 부분이 많다. 
- 종속관계에 있는 클래스가 이전 클래스 컴파일이후 비호환될때 발생하는 부분이기도 하다.
⭐ ThreadDeath

- 더이상 사용되지 않는 Thread에 대해 Thread.stop() method가 호출 될 때
- 삭제되는 Thread에서 Insatnce가 throw  되며 발생
⭐ AssertionError

- Assertion이 실패한 경우 발생 

* Assertion : 해당 지점에서 개발자가 반드시 참(true)로 표출되어야 하는 표현 논리식 
ex). assert[boolean];  assert[boolean] : [표현식];

assert i<0;
assert (!pageNo.equals(""));
assert age > 0 : "나이는 음수가 될 수 없습니다:"+age;
assert ((i/2*23-12)>0):checkValue();


private void register(MemberInfo member) {

    assert Member != null:"MemberInfo cannot be null";
    assert member.getId() != null && !member.getId().equals("");
	...
    
}
⭐ VirtualMachineError

- JVM(JavaVirtualMachine)이 손상되거나 리소스 부족시 발생

 

📚Checked Exception

⭐ 컴파일 시점에서 예외 발생 처리 확인 
⭐ RuntimeException을 상속하지 않는 클래스 
⭐ 반드시 에러 처리필요 (try/catch throw)포함
⭐ transaction 처리시 - 예외 발생시 Rollback수행 X
* 대표적인 에러클래스 
- IOException: 파일 또는 네트워크 연결에서 읽기 또는 쓰기와 같은 입력/출력 작업과 관련된 오류
- SQLException: 데이터베이스 액세스 및 쿼리와 관련된 오류
- ClassNotFoundException: 동적으로 클래스 로드와 관련된 오류
- InterruptedException: 스레드 중단 및 동기화와 관련된 오류의 경우

 

🧨Checked Exception이 Rollback이 안되는이유 

기본적으로 Checked Exception은 복구가 가능한 메커니즘으로, 만약 특정 이미지 파일을 
전송하는 함수에서 이미지를 찾지 못했을때 기본 이미지를 전송하는 복구전략을 가질수 있기에 
Rollback은 진행 하지 않는다는 의미입니다.

📚 Runtime Exception(Unchecked Exception)

명시적으로 예외처리를 하지 않아도 컴파일 후 진행시에는 예외처리가 발생하지 않지만 런타임시에 발생을 할수 있는 예외이다. 제일 많이 발생하는 에러로는 NullPointerException이 있다.  

⭐ 런타임 단계에서 확인 가능
⭐ RuntimeException을 상속하는 클래스 
⭐ 에러 처리 강제하지 않음
⭐ transaction 처리시 - 예외 발생시 Rollback수행 O
* 대표적인 에러클래스 
- NullPointerException : 실제 값이 아닌 null을 가지고 있는 객체/변수를 호출할 때 발생
- ArrayIndexOutOfBoundsException : 배열의 Index가 유효한 범위를 벗어났을때 발생
- ArithmeticException : 예외적 산술조건시 발생 (ex. 0으로 데이터를 나눌때 발생)
- IllegalArgumentException : 적합하지 않거나(illegal) 적절하지 못한(inappropriate) 인자를 메소드에
                             넘겨주었을 때 발생
- NumberFormatException : 숫자 형식 오류일때 발생 ( 숫자가 아닌 문자열로 데이터가 누적시 발생 )

 

* 참고 : 프로젝트를 하다 보면 Sparrow(스패로우)툴을 통해서 프로젝트 보안 점검을 돌릴때가 발생한다. 이때 제일 많이 걸리는 부분은 NullPointException이다. 값을 비교할때 실제 존대하는 값을 먼저 비교해야 해당 내역에 체크가 발생하지 않는다. (이건 정말 각인을 하고 프로그램을 짜야한다. 왜냐면 무조건 걸리니깐... 보안 점검툴을 하지 않는 사이트는 앞으로 더욱더 없어질것이다....)

🧨NullPointException발생 

if(BATCH_OPTION.equals("true")) {

        setDataMigration(timeMap);																
        
}		

🧨NullPointException 미발생

if("true".equals(BATCH_OPTION)) {

        setDataMigration(timeMap);																

}

 

🧨 그러면 Unchecked Exception이 발생할때 try-catch가 없다면??

- 발생한 Exception은 호출스택(call stack)의 최상단까지 올라감
- Java최상단 Main()메소드에서 잡히지 않는다면 Exception은 결국 JVM까지 올라감
- JVM은 Exception을 받게되면 console에 stack trace를 프린트 한 후 non-zero exit code로 
  프로그램을 종료(terminate)
- Unchecked Exception을 명시적으로 상용한다면 프로그램이 갑자기 종료 되지 않도록 조심해야함

 

📚 Throwable 클래스

Exception과  Error의 공통 부모클래스는 Object클래스와 Throwable 클래스를 상속받아 처리 하는 구조이다ㅏ. 

Exception이나 Error를 처리할때 Throwable로 처리해도 무관한다. 

 

⭐Throwable에 생성된 생서자 

Throwable()
Throwable(String message)
Throwable(String message, Throwable cause)
Throwable(Throwable cause)

아무런 매개 변수 없는 생성자는 기본 생성, 예외 배시지를 String으로 넘겨주고 별도의 예외 원인또한 
Throwable객체로 전달 가능

 

⭐ Throwable클래스에 선언되어있고 Exception클래스에서 Overriding한 메소드중 가장 많이 사용하는 메소드

 

🧨 e.getMessage();

    - 오류에 대한 기본적인 내용을 출력해준다. 상세하지 않다.
    - 아주 간단한 형태의 예외 출력 메시지
🧨 e.toString()

    - e.toString()을 호출한 결과는 java.lang.ArithmeticException: / by zero 이다.
    - e.toString()은 e.getMessage()보다 더 자세한 예외 정보를 제공한다.
    - 예외 클래스 이름도 제공
🧨 e.printStackTrace()

    - 메소드 getMessage, toString과는 다르게 printStackTrace는 리턴값이 X
    - 메소드가 내부적으로 예외 결과를 화면에 출력
    - printStackTrace는 가장 자세한 예외 정보를 제공
    - 문자열을 출력하는게 아니라 어떤 소스코드를, 어떤 로직을 통해서 에러가 발생했는지에 
      대한 정보를 보여줌

 

📚예외처리

예외처리 방법에는 예외복구, 예외 처리 회피, 예외 전환 방법이 존재 

 

⭐ 예외 복구 

    - 예외 상황 파악 및 문제 해결을 통한 정상 상태 변환
    - 예외를 잡아 일정시간, 조건 만큼 대기 및 재시도 진행 
    - 최대 재시도 횟수를 넘기면 예외 발생
    
 public sendFile(String fileName)() {
        File file;
        try {
                file = FileFindService.find(fileName);
        } catch (FileNotFoundException e){ 
                // 기본 파일을 찾아서 전송한다.
                file = FileFindService.find("default.png");
        }

        send(file);
        }
}

⭐ 대분분 상황에서 예외에 대한 복구가 불가하기 때문에 exception을 통한 내역이 아닌 
    름제어 형태로 진행 하는 부분이 좋다.

public void sendFile(String fileName){
        if(FileFindService.existed(filename)){
                // 파일이 있는 경우 해당 파일을 찾아서 전송한다.
                send(FileFindService.find(fileName));    
        }else{
                // 파일이 없는 경우 기본 이미지를 전송한다.
                send(FileFindService.find("default.png"));    
        }
}
⭐ 예외 처리 회피

    - 예외 처리를 직접 처리 하지 않고 호출한 쪽으로 throw 방법
    - 예외 처리 필요하다면 처리 후 전달 필요 
    - 긴밀한 역활분담을 하는 관계가 아니라면 처리후 전달 (무책임)
    
public Object checkMethod() throws IOException {
        ...
}
⭐ 예외 전환

    - 예외 회피와 비슷하게 메서드 밖으로 예외를 던지지만 적절한 예외로 전환 후 throw
    - 명확한 의미 전달을 위한 적합한 의미로 변환
    - 예외 처리를 단순하게 하기 위해 포장(wrap) 가능
    
public Object method() {
        try {
                ...
        } catch (IOException e) {
                throw new CustomException ("IOException 발생");
        }
}

public class CustomException extends RuntimeException{
    public CustomException(String message) {
        super(message);
    }
}

 

 

📚용어정리

🤝에러(Error)

입력값에 대한 처리 불가, 프로그램 Runtime중 참조된 값오류 및 정상 어플리케이션 흐름을 벗어났을때
시스템에 비정상적인 상황이 발생한 경우로 주로 JVM이 발생 함에 따라 어플리케이션 코드에서는 제어불가
🤝예외(Exception)

입력값에 대한 제어는 불가하나 프로그램 실행중에 잘못 참조된 값에 대한 정상 프로세스를 어긋났을때
JAVA는 Exception을 개발자 직접처리 가능함에 따라 예외 상황 예측 및 핸들링 가능
🤝Checked Exception

RuntimeException을 상속하지 않는 클래스로 명시적 예외처리 필요(try/catch)
컴파일 시점에 확인 가능하나, Tracsaction상태안에서 발생하면 Rollback 불가 ❌
🤝Unchecked Exception

RuntimeException을 상속한 클래스 🙆
명시적 예외 처리를 하지 않으며 런타임 시점에 확인가능
Transaction안에서 발생시 Rollback가능
🤝예외(Checked Exception)를 처리하는 방식

1. 복구방식 : 예외 상황 파악 및 문제 해결 및 정사아상태 복구
2 예외처리 회피 : 호출한 쪽으로 전달 방식 ( throw ) 
3 예외 전환방식 : 호출한쪽으로 전달을 하지만 적절한 예외로 변환하여 전달
🤝올바른 예외 처리 방식(예외 복구 전략)

- Checked Exception일때 명확한 복구가 가능하다면 try-catch를 통해 예외처리를 하는방식이 좋다.

- 복구 불가한 Checked Exception이 발생하면 더 구체적인 Unchecked Exception을 발생 시켜 
  예외 메시지를 명확히 전달하는 방식이 좋다. 
  
- 상위 메서드로 throw 예외를 전달시 상위 메서드 책임이 증가함에 따라 발생시 처리하는 구조 선호

 

📚 마치며.

프로젝트를 하면 예외처리를 위해  Exception을 사용할때가 있습니다. 통상 Exception을 통으로 사용하는 경우가 많았었습니다. 그러나 보안 점검툴을 돌려봤을때 Exception이 발생한 exception클래스만 선언해서 사용하도록 구성이 되어있었습니다. 처음에는 try-catch로 통으로 예외처리를 하는부분이 개발자 입장에서는 편하나 어플리케이션의 구동에 서는 비효율적이고 보안점검툴에 걸려 수정해야 되는 사항을 인지하였습니다. 

이번 포스팅을 하면서 Exception을 통해 전체 내역 예외처리를 하는것보다 발생할수 있는 부분에 대해 예외만 명시하고 복구 전략을 세워 어플리케이션 단에 부하를 줄이는 방법이 더욱더 필요하다는 생각이 들었습니다. 

그리고 이번 프로젝트 기간중에 스패로우 툴에서 제일 많이 발생한것이 Null 역참조 였습니다. Null을 문자열과 비교하는 과정에서 제일 많이 발생하였는데 exception포스팅과 프로젝트 스패로우 점검 툴을 통해 Null역참조를 발생하지 않는 

클린한 코드를 짜는것이 중요하다고 느꼈습니다. 

 

다음 포스팅은 개발자들의 영원한 숙제인 Null에 대해 알아봐야겠습니다. 

https://roomname-dev.tistory.com/72

 

#Null #개발자숙제 #Null이야기

 

roomname-dev.tistory.com

 

 

🤝 Ref. https://velog.io/@jsj3282/%EC%9E%90%EB%B0%94%EC%9D%98-%EC%98%88%EC%99%B8%EC%9D%98-%EC%A2%85%EB%A5%98-3%EA%B0%80%EC%A7%80
🤝 Ref. https://velog.io/@dabeen-jung/Java-Checked-Exception-Unchecked-Exception
🤝 Ref. https://steady-coding.tistory.com/583
🤝 Ref. https://lnsideout.tistory.com/entry/JAVA-etoString-egetMessage-eprintStackTrace-%EC%98%88%EC%99%B8%EC%B2%98%EB%A6%AC
🤝 Ref. https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%97%90%EB%9F%ACError-%EC%99%80-%EC%98%88%EC%99%B8-%ED%81%B4%EB%9E%98%EC%8A%A4Exception-%F0%9F%92%AF-%EC%B4%9D%EC%A0%95%EB%A6%AC

 

 

728x90
반응형

댓글