예외처리
1.에러
1) 물리적 오류(컴파일 오류): 문법적으로 맞지 않는 문장을 만들어서 컴파일이나 실행이 되지 않는 현상
- 이클립스에서는 빨간색 에러를 표시해줍니다.
- 반드시 수정을 해서 실행을 시켜야 합니다.
2) 논리적 오류: 문법적으로는 잘못된 것이 없어서 실행이 되는데 실행 결과가 이상하게 나오는 현상
- 에러가 아니기 때문에 코드 상에는 찾기가 어렵고 메모리 값을 확인하기 위한 디버깅을 수행해서 오류를 수정
3) 예외(Exception): 문법적으로는 오류가 없어서 실행은 되지만 실행 중 특수한 상황이 발생하면 에러가 발생하는 현상
- 예외처리를 이용해서 잘못된 부분이 있으면 수정을 하고 그렇지 않으면 예외를 기록해서 프로그램을 종료하게 하거나 정상적으로 동작하도록 해주어야 합니다.
4) 단언(Assertion): 물리적 오류도 아니고 예외도 아닌데 개발자가 특수한 조건을 설정해서 조건에 맞지 않는 경우 강제로 예외를 발생시켜 프로그램을 중단시키는 것
- 운영체제 버전이 맞지 않으면 실행을 못하게 하거나 특정 포트가 사용 중이면 실행을 못하게 하는 것
2.Eclipse에서 디버그 모드로 실행
디버그 모드: 메모리에 저장된 값을 확인하기 위해서 실행하는 모드
- break point 사용 가능
break point 프로그램이 실행하다가 중단할 수 있는 중단점
- break point를 만들 때는 라인 번호 옆에 있는 거터를 선택하고 마우스 오른쪽을 클릭해서 Toggle Braek poin 메뉴를 클릭하면 됩니다.
run 메뉴의 debug를 실행하면 디버그 모드로 실행됩니다.
결과가 이상하게 나오거나 실행 중 오류가 발생해서 중단되면 중단점을 만들어서 디버그 모드로 실행해서 확인
위처럼 하기 싫으면 코드 중간 중간에 System.out.print 를 이용해서 로그를 출력해서 확인하는 방법도 있습니다.로그를 출력하는 것은 에러를 수정하고 나면 필요없는 문장이 되는데 삭제를 하지 않으면 시스템 자원을 소모하게 됩니다.
클라이언트 프로그램은 부담을 적게 줄 수 있지만 서버 프로그램은 불필요한 로그를 찍는 것이 시스템 자원을 많이 소모할 수 있습니다.
3.예외처리의 목적
1) 예외가 발생하더라도 프로그램을 중단하지 않고 계속 실행하기 위해서
2) 예외의 내용을 기록해서 예외를 수정하거나 학습용으로 사용하기 위해서
public static void main(String[] args) {
int [] ar = {100, 200};
System.out.println("예외처리의 목적");
try {
System.out.println(ar[2]);//예외 발생
}catch(Exception e) {
System.err.println(e.getMessage());
}
System.out.println("예외처리의 목적 중 하나는 예외가 발생하더라도 계속 작업을 수행하기 "
+ "위해서 입니다.");
}
- 예외가 발생했지만 맨 아래에 출력 구문을 수행
- 예외처리를 하게되면 예외가 발생하더라도 이후 구문을 전부 수행합니다.
4.자바의 예외 처리
- 자바는 모든 예외를 객체로 처리
- 자바에서 예외 처리의 최상위 인터페이스는 java.lang.Throwable
- 다시 Error(심각한 예외) 와 Exception(덜 심각한 예외)으로 분류
- Exception 은 다시 RuntimeException 과 일반적인 Exception 으로 분류
- RuntimeException 은 실행 중 jvm 에 의해서 발생하는 예외로 개발자가 처리하지 않아도 되는 예외이고 일반적인 Exception은 컴파일러가 컴파일할 때 확인하는 Exception으로 개발자가 반드시 처리를 해주어야 합니다.
- 대다수의 언어는 모든 예외를 개발자가 처리해도 되고 처리하지 않아도 문법적으로 오류가 없는데 자바는 일반적인 Exception의 경우는 반드시 예외처리를 해야 합니다.
5.자주 발생하는 예외
1) NullPointerException: null 인 참조형 변수가 자신의 멤버를 호출하는 경우에 발생하는 예외
a.b
이 경우 발생하면 a가 null이어서 발생for(임시변수 in 컬렉션)
이 경우에는 컬렉션이 null이어서 발생a[b]
이 경우 발생하면 a가 null이어서 발생
2) NumberFormatException: 숫자가 아니어서 발생하는 예외
- GUI 프로그램이나 웹 프로그램에서는 숫자를 직접 입력받을 수 없습니다.
- 문자열을 입력받은 후 숫자로 변환을 해서 사용합니다.
- 숫자로 변환할려고 할 때 숫자로 변경할 수 없는 데이터라서 발생하는 예외
3) ClassCastException: 강제 형 변환이 안되는 데이터를 강제로 형 변환할려고 해서 발생하는 예외
4) ArrayIndexOutOfBoundsException: 배열이나 List에서 사용할 수 없는 인덱스를 사용한 경우
5) ArithmeticException: 산술 연산 예외
6.예외처리 방법
try{
예외가 발생할 가능성이 있는 코드
}catch(예외처리클래스이름 변수명){
예외처리클래스이름에 해당하는 예외가 발생했을 때 처리할 구문
}catch는 클래스이름이 다르면 여러 개 반복 사용 가능
finally{
예외 발생 여부에 상관없이 무조건 수행할 구문
}
- try가 나오면 catch가 1개 이상나오거나 finally가 반드시 나와야 합니다.
- finally에는 대부분 외부 자원(파일, 네트워크, 데이터베이스 등)을 사용했을 때 정리하는 코드가 작성이 됩니다.
- finally 안에 만들지 않고 catch 다음에 적어도 수행되던데 왜 finally?
- finally에 작성한 문장은 catch 구문을 수행한 다음에 실행된다는 보장을 할 수 있지만 finally가 아닌 영역에 적은 것은 catch 구문 수행 후에 된다는 보장을 할 수 없습니다.
예외처리
1.예외처리 구조
try{
예외가 발생할 가능성이 있는 구문
}
catch(예외클래스 변수명){
예외 클래스에 해당하는 예외가 발생했을 때 처리할 구문
}
catch...
finally{
예외 발생 여부에 상관없이 수행하는 구문
}
- try 가 나오면 반드시 1개 이상의 catch 나 finally가 와야 합니다.
- catch는 여러 번 나올 수 있는데 위쪽의 catch에 아래쪽 catch 보다 상위 클래스 예외를 처리하는 것은 안됩니다.
- 상위 클래스 타입의 참조형 변수에는 하위 클래스 타입의 인스턴스 참조를 대입할 수 있습니다.
- try, catch, finally 별도의 블럭이기 때문에 각 블럭에서 만든 변수는 그 블럭에서만 사용 가능
2.최상위 예외
java.lang.Trowable
- 메소드
- String getMessage(): 예외 내용을 문자열로 리턴
- void printStackTrace(): 예외 발생 내역을 역추적해서 출력
3.도달할 수 없는 코드 에러
try {
int [] ar = {100, 300};
System.out.println(ar[2]); //ArrayIndexOutOfBoundsException 발생
}
//Exception 클래스가 ArrayIndexOutOfBoundsException 의 상위 클래스라서
//예외가 발생하면 Exception이 처리
//아래 catch 구문은 도달할 수 없는 코드가 됩니다.
catch(Exception e) {
System.err.println(e.getMessage());
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("예외가 발생했습니다.");
//예외 메시지 내용을 출력
//출력하는 텍스트 색상을 변경하기 위해서 out 대신에 err 사용
System.err.println(e.getMessage());
}
4.모든 예외를 하나의 catch에서 처리하고자 할 때는 예외 클래스를 Exception 이나 Throwable을 설정하면 됩니다.
5.throws
- 메소드를 만들 때 매개변수 뒤에 throws를 기재하고 예외클래스 이름을 작성하면 이 메소드를 호출한 곳에서 예외를 반드시 처리해야 합니다.
- 자바는 RuntimeException 이외에 예외가 발생할 가능성이 있는 메소드의 경우 예외 처리를 강제하는 경우가 있습니다.
- main 메소드에 throws 예외클래스 이름을 붙이면 예외처리를 하지 않아도 됩니다.
- main 메소드는 jvm이 호출하는 메소드라서 main에서 예외를 다른곳에서 처리하도록 하면 jvm이 예외를 처리하게 됩니다. 권장하지는 않습니다.
6.예외처리를 반드시 해야 하는 경우
java.lang.Thread 클래스의 sleep 이라는 메소드는 밀리초 단위를 매개변수로 받아서 매개변수 만큼 스레드를 중지시켜주는 메소드 입니다.
이 메소드를 이용해서 10초 동안 1초마다 Hello Exception 출력하기
public static void main(String[] args) {
int i = 0;
while(i < 10) {
System.out.println("Hello Exception");
try {
//sleep 메소드는 InterruptedException 이 발생할 가능성이 있으므로
//이 예외에 대한 처리를 해야주어야만 합니다.
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i = i + 1;
}
}
7.예외 강제 발생
- 예외가 발생할 상황이 아닌데 강제로 예외를 발생시킬 수 있는데 이 때는 throw 예외객체
- 예외 객체를 만들 때는 new 예외클래스이름(메시지) 형태로 작성
8.사용자 정의 예외 클래스
- Exception 클래스로부터 상속받아서 생성
9.try - with - resources
- 1.7 버전부터 지원
try(인스턴스 생성){
인스턴스를 사용
}catch(예외 클래스 이름 변수명){
예외처리 구문
}
try( )안에서 생성한 자원은 예외 발생 여부에 상관없이 catch 구문 뒤에서 자동으로 해제를 합니다.
- try( )안에서 생성한 자원은 close()를 호출할 필요가 없습니다.
예전 구문
Socket socket = null;
try{
socket = 소켓 생성
socket 사용;
}catch(예외클래스 변수명){
예외가 발생했을 때 처리할 구문;
}finally{
socket.close();
}
- 1.7이후에 가능한 구문
try(Socket socket = 소켓생성){
socket 사용;
}catch(예외클래스 변수명){
예외가 발생했을 때 처리할 구문;
}
- 소켓은 try - catch 구문을 나오면 자동으로 자원 해제가 됩니다.
'Language_Study > JAVA' 카테고리의 다른 글
[JAVA, App] 12.Interface (0) | 2020.12.25 |
---|---|
[JAVA, App] 11.Package (0) | 2020.12.25 |
[JAVA, App] 9.추상메소드 (0) | 2020.12.23 |
[JAVA, App] 8.상속 (0) | 2020.12.23 |
[JAVA, App] 7.클래스 (0) | 2020.12.23 |