자바에서는 컴파일 에러(compile-time error)와 런타임 에러(runtime error)가 발생한다.
에러(Error)는 수습될 수 없는 심각한 오류, 예외(Exception)는 처리 가능한 오류이다.
Exception은 프로그램 실행시 예상치 못한 일로 인해 발생할 수 있는 에러를 말한다.
Java에서 ‘의미적 제약(semantic constraint)’을 위반했을 때 JVM은 프로그램에게 Exception(예외)이라는 에러가 발생했다고 알린다.
어떤 언어는 이런 에러가 발생했을 때 프로그램을 강제 종료한다.
이러한 예외는 프로그래밍시에 흔히 발생할 수 있는 일로 이러한 일이 발생했을 때 프로그래머가 원하는 방향으로 움직이도록 만드는 일을 예외처리(Exception Handling)라고 하고, 예외처리는 애플리케이션의 정상적인 흐름을 유지할 수 있도록 오류를 처리하는 강력한 메커니즘이다.
자바는 예외가 발생했을 경우, JVM에서 예외를 던지고(Throw), 예외가 발생한 지점에서 프로그래머가 지정해 놓은 위치로 제어의 비지역이동(non-local jump)이 발생한다.
예외는 발생한 지점에서 ‘던진다(throw)”고 하고 제어가 이행된 위치에서 ‘잡는다(catch)’라고 한다.
배열의 인덱스 범위를 벗어나서 접근하려 할 때 예외가 발생한 경우다.
Runtime Exception
public class RuntimeExceptionEx01{
public static void main(String[] args){
int i=0;
String strArr[]={
"Hello World", "Array", "Example"
};
while(i<4){
System.out.println(strArr[i]);
i++;
}
}
}
[결과]
Hello World
Array
Example
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index 3 out of bounds for length 3 at
ch10.RuntimeExceptionEx01.main(RuntimeExceptionEx01.java:11)
try{
예외 발생 예상 코드 블록;
} catch (예외_발생_예상_클래스_타입1 타입변수명1){
타입1 예외 발생시 처리할 내용;
} catch (예외_발생_예상_클래스_타입2 타입변수명2){
타입2 예외 발생시 처리할 내용;
} finally {
예외 발생과 상관없이 처리해야 할 내용(try~catch블럭에서 return문이 있어도 실행)
}
public class ExceptionFinallyEx01{
public static void main(String[] args){
int i=0;
String[] strArr = {
"Hello world",
"My name",
"GilDong"
};
while(i < 4){
try{
System.out.println(strArr[i]);
i++;
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("index 값 재설정");
i = 0;
}finally{
System.out.println("finally block 실행");
}
}
}
}
[결과]
Hello world
finally block 실행 //예외와 상관없이 무조건 실행된다.
My name
finally block 실행
GilDong
finally block 실행
index 값 재설정 //catch block(i 변수값을 0으로 초기화)
finally block 실행
Hello world //while문이 다시 반복적으로 실행됨
finally block 실행
My name
...
public class RestCodeTryCatchEx1{
public static void main(String[] args){
try{
int data=50/0; //예외가 throw된다.
//상위 코드에서 예외가 발생하면 나머지 코드는 실행되지 않는다.
System.out.println("나머지 코드");
}catch(ArithmeticException e){
System.out.println(e);
}
}
}
[결과]
java.lang.ArithmeticException: / by zero
public class RestCodeTryCatchEx1{
public static void main(String[] args){
try{
int data=50/0; //예외가 throw된다.
}catch(ArithmeticException e){
System.out.println(e);
}
}
System.out.println("나머지 코드");
}
[결과]
java.lang.ArithmeticException: / by zero
나머지 코드
return_type method_name throws throwExceptionClass [, otherExceptionClass...]
public void runMethod() throws IOException{
code block;
}
throw new throwExceptionClass("예외 내용");
public void runMethod() throws Exception{
...
if(조건) throw new Exception("조건 불만족");
...
}
public class TestThrowUnChk{
public static void validate(int age){
if(age>18){
throw new ArithmeticException("투표 자격 없음");
}else{
System.out.println("투표 자격 있음");
}
}
//main method
public static void main(String[] args){
validate(13);
System.out.println("나머지 코드...");
}
}
[결과]
Exception in thread "main" java.lang.ArithmeticExcemption: 투표 자격 없음
at ch12.testthrow.TestThrowUnChk.validate(TestThrowUnChk.java:6)
at ch12.testthrow.TestThrowUnChk.main(TestThrowUnChk.java:14)
public class TestThrowChk{
public static void method() throws FileNotFoundException{
FileReader file = new FileReader("abc.txt");
BufferedReader fileInput = new BufferedReader(file);
throw new FileNotFoundException();
}
//main method
public static void main(String[] args){
try{
method();
}catch(FileNotFoundException e){
e.printStackTrace();
}
System.out.println("나머지 코드...");
}
}
[결과]
java.io.FileNotFoundException: abc.txt (No such file or directory)
나머지 코드...
public class NullPointerClass{
public static void main(Stirng[] args){
crunch(null);
}
static void crunch(int[] a){
mash(a);
}
static void mash(int[] b){
System.out.println(b[0]);
}
}
Exception in thread "main" java.lang.NullPointerException
at ch12.callstack.NullClass.mash(NullClass.java:11)
at ch12.callstack.NullClass.crunch(NullClass.java:8)
at ch12.callstack.NullClass.main(NullClass.java:5)
Overview (Java SE 11 & JDK 11 )
public class ServerTimedOutException extends Exception{
private int port;
public ServerTimedOutException(String message, int port){
//Exception 클래스에 예외 메시지 전달을 위해 super를 이용하여 상위 생성자 호출
super(message);
this.port = port;
}
public int getPort(){
return port;
}
}
[사용예]
throw new ServerTimedOutException("연결할 수 없습니다", 80);
try{
connect("ProductServer");
}catch(ServerTimedOutException se){
System.out.println("오류 캐치, rethrown");
throw se;
}
public class ExceptionUserDefined{
public void connect(String serverName) throws ServerTimedOutException{
booelan success;
int port = 80;
success = open(serverName, port);
if(!success){
throws new ServerTImedOutException("연결할 수 없습니다", port);
}
}
public boolean open(String serverName, int port){
//method body
return false;
}
public void findServer(){
try{
connect("ProductServer");
}catch(ServerTimedOutException se){
System.out.println("서버 접속시간 초과, 대체 서버 시도");
try{
connect("AlterProductServer");
}catch(ServerTimedOutException rse){
System.out.println("Error: " + rse.getMessage() +
"포트에 연결 " + rse.getPort());
}
}
}
public static void main(String[] args){
ExceptionUserDefined e = new ExceptionUserDefined();
e.findServer();
}
}
try{
int[] arr = new int[3];
arr[3] = 10/0;
}catch(ArithmeticException ae){
ae.printStackTrace();
}catch(ArrayIndexOutOfBoundsException aie){
aie.printStackTrace();
}catch(Exception e){
e.printStackTrace();
System.out.println("Exception message: "+
e.getMessage());
}
[결과]
java.lang.ArithmeticException: / by zero
at ch11.ExceptionStackTrace.main(ExceptionStackTrace.java:9)
public class A{
public A() throws IOException{}
}
public class B extends A{
public B() throws IOException{}
}
public class MultiCatchException{
public static void main(String[] args){
try{
int[] arr = new int[3];
arr[3] = 10/0;
}catch(ArithmeticException | ArrayIndexOutOfBoundsException ae){
System.out.println("예외가 발생하였습니다 : " + ae.getMessage());
}
}
}
public class NestedTryBlockEx2{
public static void main(String[] args){
//outer (main) try block
try{
//inner try block 1
try{
//inner try block 2
try{
int arr[] = {1,2,3,4};
System.out.println(arr[10]);
}catch(ArithmeticException e){
System.out.println("Arithmetic exception");
System.out.println*" inner try block 2");
}
}catch(ArithmeticException e){
System.out.println("Arithmetic exception");
System.out.println("inner try block 1");
}
}catch(ArrayIndexOutOfBoundsException e4){
System.out.println(e4);
System.out.println(" outer (main) try block");
}catch(Exception e5){
System.out.println("Exception");
System.out.println(" handled in main try-block");
}
}
}
[결과]
java.lang.ArrayIndexOutOfBoundsException: Index 10 out of
bounds for length 4 outer (main) try block
public class ResolveTryCatchEx2{
public static void main(String[] args){
try{
int data1=50/0; //예외 발생
}catch(Exception e){
//catch 블럭에서 예외 발생
int data2=50/0;
}
System.out.println("나머지 코드");
}
}
[결과]
Exception in thread "main"
java.lang.ArithmeticException: / by zero at
ch12.resolveexception.NonResolveTryCatchEx2.main(NonResolveTryCatchEx2.java:8)
public class ResolveTryCatchEx2{
public static void main(String[] args){
try{
int data1=50/0; //예외 발생
}catch(Exception e){
try{
int data2=50/0; //예외 발생
}catch(Exception innere){
innere.printStackTrace();
//예외 처리 코드 작성
}
}
System.out.println("나머지 코드");
}
}
[결과]
Exception in thread "main"
java.lang.ArithmeticException: / by zero at
ch12.resolveexception.ResolveTryCatchEx2.main(NonResolveTryCatchEx2.java:9)
나머지 코드
public class TestFinallyEx1{
public static void main(String[] args){
try{
System.out.println("try block내 실행...");
int data=25/0;
System.out.println(data);
}catch(NullPointerException e){
System.out.println("catch block내 실행...");
System.out.println(e);
}finally{
System.out.println("finally block 항상 실행");
}
System.out.println("나머지 코드...");
}
}
[결과]
try block내 실행...
finally block 항상 실행
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ch12.testfinally.TestFinallyEx1.main(TestFinallyEx1.java:8)