▶에러의 종류
-, 컴파일에러
; 을 안찍어줬다던지 new를 빼먹었다던지 소스코드의 구문 오류로 인해서 컴파일 자체가 불가능한 상태를 말하며 컴파일러에서 빨간색으로 표시가 되는 경우에 해당한다.
프로그램을 실행하기 전에 발견되므로 상대적으로 고치기 쉽다.
-. 런타임에러
구문상의 에러는 없지만, 프로그램이 실행되는 과정에서 다양한 경우의 수에 대응하지 못하여 발생되는 예외상황이다.
런타임 에러가 발생이 되면 프로그램은 강제로 종료되며 우리가 프로그램의 에러라고 부르는 현상은 대부분 런타임 에러에 해당된다.
▶런타임 에러의 종류
프로그램 자체의 구조적인 문제로 인한 논리적 오류와 자바 가상머신 자체의 문제로 인한 오류, 그리고 예외가 있다.
-. 논리오류
코드 자체에 논리적 모순이 생기는 상황
-. 자바가상머신 자체의 오류
자바 자체에도 버그가 있다. 이는 프로그레머가 책임질 수 있는 오류가 아니며 오라클에서 주는 자바오류API를 보던지 오라클과의 소통을 통해 이를 해결해야한다.
-. 예외(Exception)
프로그램 실행 중에 발생할 수 잇는 예기치 않은 사건으로, 프로그래머의 노력으로 처리할 수 있다.
자바 가상 머신은 프로그램 실행 중에 예외가 발생하면 관련된 에외 클래스로부터 예외 객체를 생성하여 프로그램에서 지정된 예외처리 구문으로 넘긴다.
예외가 발생하면 프로그램에 지정된 예외 처리 구문이 자바 가상머신에 의해 호출이 되고, 이 때 전달되는 예외 객체를 넘겨받아 적절한 처리를 수행한다.
▶자바 예외 오류
예외상황오류란 프로그램의 문법적으론 오류가 없지만, 데이터타입의 충돌, 배열 범위의 초과등 여러가지 예외로 인하여 오류가 발생하는 것을 말한다.
예외상황의 오류의 가장 치명적인 문제는 프로그램이 정상적인 종료가 되지 않은 다는 것이다.
프로그램이 위에서 아래로 실행하다가 예외상황이 발생한 라인을 만났고 에러를 콘솔에 출력을 한면 java프로그램은 그 즉시 실행을 중단하고 강제종료된다.
때문에 그 예외발생부분 뒤의 코드는 정상적으로 출력이 되지 않는다.
좀 더 자세히 설명하자면
만약 국민은행 어플에서 3000원이라는 값의 입력을 String으로 받았다. 물론 어플 코드 안에는 String을 int값으로 변경해주는 로직이 들어가있을텐데 어떤 변수로 예외오류가 발생이 되었다고 가정했을 때 그 국미은행 어플은 예외오류를 만나는 순간 바로 다운되어버린다.
기본적으로 문제가 발생이 되면 상태메시지창으로 사용자에게 알려주고 어플은 계속 서비스가 되어야하는데 그냥 어플이 꺼지는 것이다.
▶자바 예외 클래스 종류
▶예외상황예시 1 : NumberFormatException
위는 int 에서 string타입을 빼는 연산식이다.
Integer.parseInt를 통해 String을 int로 변환하여 출력하였고 age1을 통해 정상적인 값이 출력되는 구문이다.
이 구문도 프로그램 구문상으론 문제는 없다.
그래서 컴파일 에러라는 빨간색 줄도 java에서는 표시해주지않았다.
그러나 year2에는 "뭘까"라는 숫자로 변경하지 못하는 문자데이터가 대입되어있고 2022 - "뭘까" +1 의 계산은 성립되지않는다.
이때 java는 빨간색 에러메시지를 통해 Exception: 예외상황이 발생했다고 개발자에게 안내를 해주는 것이다.
여기서 중점으로 봐야할 것은 첫번째 줄과 마지막줄인데
NumberFormatException : For input string: 숫자가 들어와야하나 String이 들어와서 에러가 발생되었으며
제일 마지막 Main의 13번째줄이 문제라는 것을 java는 친절하게 설명해주고있다.
▶예외상황 2: ArrayIndexOutOfBoundsException
이 구문도 컴파일을 하는데에 문제가 없지만 자세히 보면 배열의 크기에서 오류가 날 것이다.
3개의 저장공간이 있는 배열에 i<5를 통해 5개의 값을 넣으려고 하기 때문이다.
그래서 0,1,2라는 배열의 저장공간이 있는 곳에선 for구문을 통해 값이 정상적으로 담겨졌지만 저장공간을 벗어난 3번째 데이터부턴 예외오류가 발생이 되었고 프로그램이 강제종료되었다.
또한, 빨간색의 오류 내용을 보고 ArrayIndexOutOfBoundsException이라는 오류 이름으로 예외처리가 발생이 되었고 Main02의 9행 부분을 수정해야한다는 것을 우린 알 수 있다.
▶자바 예외 처리
자바에서는 try ~ catch ~ finally 구문을 통해 프로그래머가 예외 상황에 대응할 수 있도록 하고있다.
try{
// 기본적으로 실행되는 부분
} catch( 예외 클래스 이름 객체이름) {
// try 블록에서 예외가 발생한 경우 이곳으로 제어가 넘어온다.
} finally{
// 예외 상황의 발생 여부에 상관 없이 무조건 실행되는 부분
// finally 블록은 생략 가능하다.
}
try 블록 실행 도중 catch에서 명시한 예외 클래스에 해당하는 런타임 에러가 발생하면, try 블록을 즉시 중단하고 catch 블록이 실행 된 후, finally 블록이 실행된다.
만약 예외가 발생하지 않을 경우에는 try 블록 종료 후 finally 블록이 실행된다.
▶자바 예외 처리 예시
try안에 실행하고 싶은 구문을 입력한다. 그런데 개발자는 Interger.parseInt 구문에 실행할 수 없는 예외오류가 발생될 것으로 예상되어 try catch구문을 사용하였다.
catch()안에 이 오류 클래스명을 적고 이 클래스를 받을 수 있는 임시 파라미터(=e)를 작성하였다.(보통 예외처리에 대한 파라미터 객체명을 e를 주로 사용한다) 그러면 try안에서 어떠한 오류가 발생이 되었을 때 그 오류가 catch() 안에 있는 오류와 동일하다면 java는 catch안으로 들어가게된다.
catch안에는 오류가 났을 경우 출력해야할 "에러가 발생했습니다"구문이 들어있고 해당내용이 출력이 되어사용자에게 오류내용을 안내해줄 수 있다. 게다가 try catch구문을 사용하면 중간에 프로그램이 멈추지도 않는다!
즉, 예외가 발생하던 발생하지 않던 try 문으로 처리를 해두면 정상적인 출력이 가능하다.
예외가 발생할 가능성이 있는건 try구문에 실행을 하는 것이다.
▶자바 예외 처리 원인 확인
파란색 줄이 쳐져있는 부분에 작성한 코드처럼
e 파라미터와 getMessage() 메서드를 결합시키고 출력시키면 "뭘까"때문에 오류가 발생이 되었다고 java가 출력해준다.
조금 더 에러구문을 자세하게 확인하고 싶다면 printStackTrace() 메서드를 사용한다.
try catch구문을 사용하지 않았을 때 콘솔창에 출력이 되었던 빨간 메세지와 동일한 오류가 출력이 되는데 try catch 구문 덕분에 기존과는 달리 프로그램 이 중간에 강제종료 되지 않고 "프로그램종료"가 출력이 되어 java가 계속 실행되는 것을 알 수 있다.
▶try catch구문 예외상황
보면 e.printStackTrace()가 syso의 프로그램 종료보다 더 빨리 입력되어있음에도 불구하고 출력창에는 "프로그램종료"가 에러메시지보다 먼저 출력이 되었다.
이는 단순하게 e.printStackTrace()가 먼저 실행된게 맞으나 에러 메시지의 내용이 많아 출력될 때의 조금의 시간차로 인해 오류내용이 밑으로 가는 것이다.
try안 구문의 예외에러명은 NumberFormatException이다. 그러나 위 코드에는 catch구문에 IndexOutOfBoundsException을 입력하였다.
이 소스코드에 부합되는 적당한 예외처리가 되지않은 것이다.
그래서 발생가능성이 있는 예외에 대한 처리가 제대로 이루어지지않았기에 프로그램 중간종료가 되어버렸고 프로그램종료라는 가장 마지막에 출력되어야하는 문구가 출력이 되지 않은 것을 볼 수 있다.
▶Catch블록을 사용한 복잡한 에러처리
try{
} catch( NumberFormatException e ){
} catch( ArrayIndexOutOfBoundsException e ){
}
e는 지역변수임으로 한번 더 사용해도 에러가 발생이 되지 않으며, 여러 오류상황을 중첩하여 에러가 예상되는 상황에 대해 복수로 명시하는 것이 가능하다.
▶Exception 클래스
자바에서 예외상황을 의미하는 모든 클래스들의 최상위 클래스이다.
이 클래스의 이름으로 catch블록을 구성하면, 모든 예외 상황에 일괄적으로 대응할 수 있지만, catch 블록이 세분화된 경우와는 달리 상황 별 개별적인 처리는 불가능하다.
Exception 클래스에 대한 예외 처리는 대부분 맨 마지막 catch 블록에 명시하여 '마지막 알 수 없는 에러'를 의미하도록 구성하는 것이 일반적이다.
try{
} catch( NumberFormatException e ){
} catch( ArrayIndexOutOfBoundsException e ){
} catch(Exception e){
}
excepiton 예외처리는 개발자도 인식하지 못했던 예외를 대비하는 것으로 마지막에는 꼭 추가해주어야한다.
▶catch구문의 순서
catch의 순서를 보면 NumberFormatException이나 ArrayIndexOutOFBoundsException이나 모두 Exception예외에 잡힐 수 있다. 그럼 Exception을 제일 위에 사용을 하면 안될까?
해보면 에러가 난다.
이유는 exception은 최상위 클래스로 모든 에러가 잡히기에 밑의 catch클래스 2개에는 소스코드가 들어갈 기회가 없는 것이다.
그래서 catch에는 에러가 발생이 되고 exception은 맨 마지막에 작성해야하는 것이다.
NumberFormatException과 ArrayIndexOutOfBoundsException은 서로 동일선상에 있는 수준의 에러이기에 순서 상관없이 둘은 에러가 발생되지 않는다.
그러면 exception만 사용해도 되는거 아닐까?
이부분은 업무적인 부분으로 나뉘게된다.
모든 에러가 발생이 된 상황은 다르고 그 상황을 사용자에게 안내창을 통해 모두 피드백을 주고 싶다면 catch문을 쪼개야하는 것이지만, 모든 에러를 뭉쳐서 "에러발생"으로 사용자에게 안내만 해줘도 된다면 exception하나만 사용을 해도 된다는 것이다.
▶finally
finally로 try에 오류가 있건 없건 무조건적으로 실행을 시켰다.
▶여러 객체 'e'의 기능
-. e.getMessage()
간략한 에러 메시지를 리턴하고 e.getLocalisMessage()도 같은 기능을 한다.
-. e.printStackTrace()
실제 예외 상황시에 출력되는 메시지를 강제로 출력한다.
개발자가 catch 블록 안에서 예외 상황을 분석하기 위한 용도로 사용한다.
'국비필기노트 > Java' 카테고리의 다른 글
자바(java)_제너릭, 컬렉션프레임워크(Collection Framework), ArrayList, HashMap (0) | 2022.04.01 |
---|---|
자바(java)_Calendar 클래스 (0) | 2022.03.31 |
자바(java)_정규표현식 (0) | 2022.03.29 |
자바(java)_Math 클래스 (0) | 2022.03.28 |
자바(java)_String 클래스 (0) | 2022.03.28 |