즐겁게!! 자신있게!! 살아보세!!

재밌는 인생을 위하여! 영촤!

Language_Study/JAVA

[JAVA, App] 10.예외처리

Godwony 2020. 12. 25. 11:14
반응형

예외처리

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