예외 : 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류
=> 예외 처리 코드 작성하면 정상 작동 가능
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 |