프로그램 오류
논리적 에러 : 작성 의도와 다르게 동작하는 에러
컴파일 에러 : 컴파일 할 때 발생하는 에러
package chapter08;
//컴파일 에러
public class Study01Ex1 {
public static void main(String[] args) {
system.out.println(args[0]);
}
}
※자바 컴퍼일러 역할
- 구분 확인
- 번역
- 최적화
ex) int i = 3 + 5; - 생략된 코드 추가
ex) 클래스이름 extends Object
런타임 에러 : 실행할 때 발생하는 에러(프로그램 종료)
package chapter08;
public class Study01Ex2 {
public static void main(String[] args) {
System.out.println(args[0]);
}
}
※Java 런타임 에러 종류
- 에러(error) : 프로그램 코드에 의해 수습될 수 없는 심각한 오류
- 예외(exception) : 프로그램 코드에 의해서 수습될 수 있는 미약한 오류
예외 처리(exception handling)
정의 : 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것
목적 : 프로그램의 비정상 종료를 막고, 정상적인 실행 상태를 유지하는 것
예외 클래스의 계층 구조(Java 11 api documentation)
Exception 클래스 : 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외
RuntimeException 클래스 : 프로그래머의 실수로 발생하는 예외
try-catch문
try {
//예외가 발생할 가능성이 있는 문장, 구문
} catch (Exception1 e1) {
// Exception1이 발생했을 경우, 이를 처리하기 위한 구문 작성
} catch (Exception2 e2) {
// Exception2이 발생했을 경우, 이를 처리하기 위한 구문 작성
} catch (ExceptionN eN) {
// ExceptionN이 발생했을 경우, 이를 처리하기 위한 구문 작성
}
- try-catch문 흐름
1. try 블럭 내에서 예외가 발생한 경우
1)발생한 예외와 일치하는 catch블럭이 있는지 확인
2) 일치하는 catch 블럭을 찾게 되면, 그 catch 블럭 내의 문장들을 수행하고
전체 try-catch문을 빠져나가서 그 다음 문장을 계속해서 수행
만일 일치하는 catch블럭을 찾지 못하면, 예외는 처리되지 못함 - try 블럭 내에서 예외가 발생하지 않은 경우
1) catch 블럭을 거치지 않고 전체 try-catch문을 빠져나가서 수행을 계속함
package chapter08;
//try 블럭 내에서 예외가 발생한 경우
public class Study02Ex1 {
public static void main(String[] args) {
System.out.println(1);
try {
System.out.println(0/0);
System.out.println(2);
} catch (Exception e) {
System.out.println(3);
} //try-catch문 끝
System.out.println(4);
}
}
package chapter08;
//try 블럭 내에서 예외가 발생하지 않은 경우
public class Study02Ex2 {
public static void main(String[] args) {
System.out.println(1);
try {
System.out.println(2);
System.out.println(3);
} catch (Exception e) {
System.out.println(4);
} //try-catch문 끝
System.out.println(5);
}
}
package chapter08;
public class Study02Ex3 {
public static void main(String[] args) {
System.out.println(1);
System.out.println(2);
try {
System.out.println(3);
System.out.println(0/0);
System.out.println(4); //실행되지 않음
} catch (ArithmeticException e) {
if(e instanceof ArithmeticException)
System.out.println("true");
System.out.println("ArithmeticException");
} catch (Exception e) { //ArithmeticException을 제외한 모든 예외가 처리
System.out.println("Exception");
}
System.out.println(6);
//try{}예외가 발생하면 이를 처리할 catch블럭으로 찾아 내려감
//일치하는 catch 블럭이 없으면 예외는 처리 안됨
//Exception이 선언된 catch블럭은 모든 예외 처리 => 마지막 catch 블럭에 작성
}
}
package chapter08;
public class Study02Ex4 {
public static void main(String[] args) {
System.out.println(1);
System.out.println(2);
try {
System.out.println(3);
System.out.println(args[0]);
System.out.println(4);
} catch (ArithmeticException e) {
if(e instanceof ArithmeticException)
System.out.println("true");
System.out.println("ArithmeticException");
}
System.out.println(5);
}
}
=> 해결
package chapter08;
public class Study02Ex4 {
public static void main(String[] args) {
System.out.println(1);
System.out.println(2);
try {
System.out.println(3);
System.out.println(args[0]);
System.out.println(4);
} catch (ArithmeticException e) {
if(e instanceof ArithmeticException)
System.out.println("true");
System.out.println("ArithmeticException");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException");
}
System.out.println(5);
}
}
printStackTrace()
예외가 발생하면 예외 객체가 생성되고 그 객체에는 예외 정보가 있음
예외 객체의 메서드에는 printStackTrace(), getMessage() 등이 있음
printStackTrace() : 예외 발생 당시 호출 스택(Call Stack)에 있었던 메서드의 정보와 예외 메시지를 화면에 출력
getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있음
package chapter08;
public class Study03Ex1 {
public static void main(String[] args) {
System.out.println(1);
System.out.println(2);
try {
System.out.println(3);
System.out.println(0/0);
System.out.println(4);
} catch (ArithmeticException e) {
e.printStackTrace(); //참조변수 a를 통해 생성된 ArithmeticException 인스턴스에 접근 가능
System.out.println("예외 메시지 : " + e.getMessage());
}
System.out.println(5);
}
}
멀티 catch 블럭
내용이 같은 catch 블럭을 하나로 합친 것(JDK1.7~)
try {
...
} catch (Exception1 e1) {
e1.printStackTrace();
} catch (Exception e2) {
e2.printStackTrace();
}
//==>
try {
} catch (Exception1 | Exception2 e) { //중복 제거
e.printStackTrace();
}
멀티 catch 블록에 쓰이는 클래스가 부모-자식 관계면 안됨
Exception1 과 Exception2의 공통 메서드만 구현부에 올 수 있음
예외 발생
예외 발생
연산자 new를 이용해서 발생시키려는 예외 클래스의 객체를 만든 다음, 키워드 throw를 이용해서 예외를 발생
package chapter08;
public class Study04Ex1 {
public static void main(String[] args) {
try {
Exception exception = new Exception();
throw exception; //예외를 발생
//throw new Exception(); //위의 코드를 한 줄로 작성
} catch (Exception e) {
System.out.println("에러 메시지 : " + e.getMessage());
e.printStackTrace();
}
System.out.println("프로그램 정상 종료");
}
}
체크드, 언체크드 예외
checked 예외 : 컴파일러가 예외 처리 여부를 체크(예외 처리 필수) Exception
unchecked 예외 : 컴파일러가 예외 처리 여부를 체크 안함(예외 처리 선택) RuntimeException
package chapter08;
//checked예외 => 예외 처리 필수 컴파일 불가
public class Study04Ex2 {
public static void main(String[] args) {
// throw new Exception(); //컴파일 에러
}
}
package chapter08;
//unchecked예외 => 예외 처리 선택. 컴파일 가능
public class Study04Ex3 {
public static void main(String[] args) {
throw new RuntimeException();
}
}
Exception은 예외 처리 필수
RuntimeException은 예외 처리 선택