본문 바로가기

Programming/자바

자바 재정리 - 예외 처리

예외 : 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류

=> 예외 처리 코드 작성하면 정상 작동 가능

 

cf. 에러 : 하드웨어 오동작, 고장 등으로 인해 프로그램이 정상 실행되지 않는 심각한 오류  => 수습 불가

 

 

 

 

예외의 종류
  • 일반 예외 (=컴파일러 체크 예외)

:  자바 소스 컴파일 과정에서 예외처리코드가 필요한지 검사해줌

 

ex. 이클립스 => 컴파일 과정에서 예외를 확인해 빨간 선 표시, 예외 처리 방법 제시

 

 

 

 

  • 실행 예외

: 컴파일 과정에서 예외처리코드를 검사하지 않는 오류

java.lang.RuntimeException 상속받음

 

 

=> 두 가지 예외 모두 예외 처리 필요함

 

 

 

 

예외 처리 코드

: 예외 (문법 오류 X)  발생 시 대응해 정상 작동하도록 하는 코드

 

=> try문에서 오류 발생하면 오류 코드 밑줄부터 실행  안 하고 catch문으로 이동함

 

finally : 예외 상관 없이 무조건 실행

 

 

  •  
public class ExceptionEx5 {

    public static void main(String[] args) {
        
        try {
            String[] data = {"a100","200"};
            int value1=Integer.parseInt(data[0]);
            int value2=Integer.parseInt(data[1]);        
            int result = value1+value2;
            System.out.println("계산 결과 : "+result);
        } catch(NumberFormatException e) {
            System.out.println("숫자만 입력해주세요");
        } finally {
            System.out.println("모두 화이팅");
        }
        
    }

}

//
계산 결과 : 300

 

 

 

  • 다중 catch
try {
	...
} catch (ArrayIndexOutOfBoundsException e) {
	예외 처리 1
} catch (NumberFormatException e) {
	예외 처리 2
}

catch 블록 여러 개일 때에도 단 하나의 catch 블록만 실행됨

=> 하나의 예외 발생 시 즉시 실행 중지하고 해당 catch 블록으로 이동해서

 

 

  • catch 순서

상위 예외 클래스가 항상 아래쪽에 위치함

 

try {
	...
} catch (ArrayIndexOutOfBoundsException e) {
	...
} catch (Exception e) {
	...
}

 

 

 

  • 멀티 catch (권장 X)

하나의 catch 블록에서 여러 예외 처리

 

try {
	...
} catch (ArrayIndexOutOfBoundsException|NumberFormatException e) {
	예외 처리 1
} catch (Eception e) {
	예외 처리 2
}

 

 

 

 

실행 예외

컴파일러가 체크하지 않으므로 개발자의 경험을 기반으로 하여 예외처리함

 

 

  • NullPointerException : null값 참조변수(객체 참조 없음)로 객체접근연산자 . 를 사용 시 발생
=> 객체 없는 상태에서 객체를 사용하려 할 때 발생
 
public class ExceptionEx2 {

    public static void main(String[] args) {
        try {
       		String name = null;
       		System.out.println("이름 : "+ name.toString());
        } catch (NullPointerException e) {
        	System.out.println("문자정보 가져올 수 없음");
        }
    }
}

 

 

 

※ 참조타입(String) : 스택에 참조값(주소번지) 저장, 힙에 문자값 저장
String hobby = "여행";
hobby = null;
=> 힙에는 "여행" 문자값 저장돼있으나 스택에는 null 저장되며 참조연결 끊김
=> 자바가 자동적으로 쓰레기수집기 구동시켜 "여행"값을 힙 메모리에서 제거할 것

 

 

 

  • ArrayIndexOutOfBoundsException : 배열의 인덱스 범위 초과 시
public class ExceptionEx3 {

    public static void main(String[] args) {
        
        try {
            int[] nums = {10,20,30,40,50};
            System.out.println(nums[5]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("배열의 인덱스 범위를 벗어났습니다");
        }
    }

}​

 

 

 

  • NumberFormatException : 숫자 변환 실패 시 (.parseInt, .parseDouble 사용)
public class ExceptionEx4 {

    public static void main(String[] args) {
        
        try {
        	String data1="100";
        	String data2="a200";
        	System.out.println(data1+data2);
        
        	int value1 = Integer.parseInt(data1);
        	int value2 = Integer.parseInt(data2);
        	System.out.println(value1+value2);
        } catch (NumberFormatException e) {
        	System.out.println("숫자만 넣어주세요");
        }
        
    }

}​

 

 

 

  • ClassCastException : 상하위 클래스 관계가 아닌데 타입 변환 시도 시
public class Driver {
    //메소드
    void Drive(Vehicle vehicle) {  
        //if (vehicle instanceof Bus) {    //타입 물어보는 명령
            Bus bus=(Bus)vehicle;
            bus.checkFare();
        //}
        vehicle.run();
    }
}


public class DriverEx1 {

    public static void main(String[] args) {
        try {
            Driver chulsu = new Driver();
            Taxi taxi = new Taxi();
            Truck truck = new Truck();
            Bus bus = new Bus();
            chulsu.Drive(bus); //실행됨
            chulsu.Drive(taxi);  //예외 처리 시작
            chulsu.Drive(truck);
        } catch (ClassCastException e) {
            System.out.println("타입 변환할 수 없습니다");
        }
    }
}

//

승차요금을 체크합니다.

버스가 달립니다.

타입 변환할 수 없습니다

 

 

 

 

예외 떠넘기기

try-catch 문 대신 메소드 호출한 곳으로 예외 떠넘기기

 

 

public void method1(){
    try{ 
        method2(); 
    }catch(ClassNotFoundException e){ //호출한 곳에서 예외 처리
       System.out.println("클래스가 존재하지 않습니다") 
    } 
} 


public void method2() throws ClassNotFoundException{ //예외를 호출한 곳으로 떠넘김
    Class class = Class.forName("java.lang.String2");
}

=> method1()에서도 다시 예외 떠넘기기 가능 -> method1 호출하는 곳에서 try-catch 사용해 예외 처리해야 함

 

 

 

 

사용자 정의 예외

예외 => 자바 표준 예외 + 사용자 정의 예외

throws : 생성자나 메소드 선언 끝(=메소드 선언부)에 사용, 다중 예외 시 쉼표로 구분

throw : 예외를 최초로 발생시킴, throw 키워드 뒤는 예외 객체 생성 코드 (ex. throw new BalanceInsuff~)

 

 

public class BalanceInsufficientException extends Exception{ //예외 선언
    //생성자
    public BalanceInsufficientException() {
    }
    
    public BalanceInsufficientException(String message) {
        super(message); //Exception 클래스의 생성자 호출
    }
}


public class Account {

    static final String BANKNAME = "신한은행";
    String accountNo;    
    String ownerName;    
    int balance;
    
    public Account(String accountNo, String ownerName, int balance) {
        this.accountNo=accountNo;  
        this.ownerName=ownerName;
        this.balance=balance;
    }
    
    public Account() {
    }
    
    void deposit (int amount) {    
        balance+=amount;
    }    
    
    int withdraw(int amount) throws BalanceInsufficientException {  //예외 발생
        if (balance<amount) {
            throw new BalanceInsufficientException("잔액 부족"); //예외 발생
        } 
        balance-=amount;
        return amount;
    }    
}


public class AccountEx1 {

    public static void main(String[] args) {
        Account chulsu = new Account();
        chulsu.accountNo = "0101-10101-1010";  
        chulsu.ownerName = "김철수";
        chulsu.balance = 1000;
        
        Account gildong = new Account();
        gildong.accountNo = "0202-020202-0202";
        gildong.ownerName = "홍길동";
        gildong.balance = 0;
        
        chulsu.deposit(5000);
        gildong.deposit(30000);
        chulsu.deposit(20000);
    
        try {
            int amount = gildong.withdraw(70000); //
            System.out.println("찾은 금액: "+amount);
        }catch(BalanceInsufficientException e) {
            System.out.println(e.getMessage());
        }
    }
}

//
잔액 부족

 

 

 

 

'Programming > 자바' 카테고리의 다른 글

자바 재정리 - 멀티 스레드  (0) 2022.09.07
자바 재정리 - API  (0) 2022.09.05
자바 재정리 - 중첩 클래스, 중첩 인터페이스  (0) 2022.08.26
자바 재정리 - 인터페이스  (0) 2022.08.25
자바 재정리 - 상속  (0) 2022.08.23