문서의 선택한 두 판 사이의 차이를 보여줍니다.
양쪽 이전 판 이전 판 다음 판 | 이전 판 마지막 판 양쪽 다음 판 | ||
study:java:javachobo:ch8 [2010/02/15 14:26] gauryan |
study:java:javachobo:ch8 [2010/02/16 06:41] gauryan |
||
---|---|---|---|
줄 53: | 줄 53: | ||
| | ||
for( int i = 0 ; i < 10 ; ++i ) { | for( int i = 0 ; i < 10 ; ++i ) { | ||
- | result = number / (int)(Math.random() | + | result = number / (int)(Math.random() |
System.out.println(result); | System.out.println(result); | ||
} | } | ||
줄 68: | 줄 68: | ||
for( int i = 0 ; i < 10 ; ++i ) { | for( int i = 0 ; i < 10 ; ++i ) { | ||
try { | try { | ||
- | result = number / (int)(Math.random() | + | result = number / (int)(Math.random() |
System.out.println(result); | System.out.println(result); | ||
} catch (ArithmeticException e) { | } catch (ArithmeticException e) { | ||
줄 125: | 줄 125: | ||
===== 예외 클래스의 계층구조 ===== | ===== 예외 클래스의 계층구조 ===== | ||
* 예외클래스 계층도 < | * 예외클래스 계층도 < | ||
- | Object --- Throwable -+- Error -+- OutOfMemoryError | + | Object --- Throwable -+- Error |
- | | | | + | | |
- | | +- ... | + | | |
| | | | ||
- | + Exception -+- IOException | + | +- Exception -+- IOException |
- | | + | | |
- | | + | +- ... |
- | | + | | |
- | | + | +- RuntimeException |
</ | </ | ||
* 예외클래스는 다음과 같이 두 개의 그룹으로 나눠질 수 있다. | * 예외클래스는 다음과 같이 두 개의 그룹으로 나눠질 수 있다. | ||
줄 183: | 줄 183: | ||
} | } | ||
</ | </ | ||
+ | |||
===== 예외 발생시키기 ===== | ===== 예외 발생시키기 ===== | ||
* 키워드 throw 를 사용해서 프로그래머가 고의로 예외를 발생시킬 수 있으며, 방법은 아래의 순서를 따르면 된다. | * 키워드 throw 를 사용해서 프로그래머가 고의로 예외를 발생시킬 수 있으며, 방법은 아래의 순서를 따르면 된다. | ||
- 먼저, 연산자 new를 이용해서 발생시키려는 예외 클래스의 객체를 만든다음 <code java> | - 먼저, 연산자 new를 이용해서 발생시키려는 예외 클래스의 객체를 만든다음 <code java> | ||
Exception e = new Exception(" | Exception e = new Exception(" | ||
- | < | + | </code> |
- 키워드 throw를 이용해서 예외를 발생시킨다. <code java> | - 키워드 throw를 이용해서 예외를 발생시킨다. <code java> | ||
throw e; | throw e; | ||
+ | </ | ||
+ | * [예제 8-9] / | ||
+ | class ExceptionEx9 { | ||
+ | public static void main(String[] args) { | ||
+ | try { | ||
+ | Exception e = new Exception(" | ||
+ | throw e; // 예외를 발생시킴. | ||
+ | // throw new Exception(" | ||
+ | } catch (Exception e) { | ||
+ | System.out.println(" | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | System.out.println(" | ||
+ | } | ||
+ | } | ||
</ | </ | ||
===== 예외의 발생과 catch블럭 ===== | ===== 예외의 발생과 catch블럭 ===== | ||
+ | * 첫 번째 catch블럭부터 차례로 내려가면서 catch블럭의 괄호()내에 선언된 참조변수의 종류와 생성된 예외클래스의 인스턴스에 **'' | ||
+ | * 검사결과가 true인 catch블럭을 찾게 되면 블럭에 있는 문장들을 모두 수행한 후에 try-catch문을 빠져나가고 예외는 처리되지만, | ||
+ | * 모든 예외 클래스는 Exception클래스의 자손이므로, | ||
+ | * [예제 8-10] / | ||
+ | class ExceptionEx10 { | ||
+ | public static void main(String[] args) { | ||
+ | System.out.println(1); | ||
+ | System.out.println(2); | ||
+ | try { | ||
+ | System.out.println(3); | ||
+ | System.out.println(0/ | ||
+ | System.out.println(4); | ||
+ | } catch (Exception e) { // ArithmeticException대신 Exception을 사용. | ||
+ | System.out.println(5); | ||
+ | } | ||
+ | System.out.println(6); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | * [예제 8-11] / | ||
+ | class ExceptionEx11 { | ||
+ | public static void main(String[] args) { | ||
+ | System.out.println(1); | ||
+ | System.out.println(2); | ||
+ | try { | ||
+ | System.out.println(3); | ||
+ | System.out.println(0/ | ||
+ | System.out.println(4); | ||
+ | } catch (ArithmeticException ae) { | ||
+ | if(ae instanceof ArithmeticException) | ||
+ | Ssystem.out.println(" | ||
+ | System.out.println(" | ||
+ | } catch (Exception e) { // ArithmeticException을 제외한 모든 예외가 처리된다. | ||
+ | System.out.println(5); | ||
+ | } | ||
+ | System.out.println(6); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | * 예외가 발생했을 때 생성되는 예외클래스의 인스턴스에는 발생한 예외에 대한 정보가 담겨져 있으며, getMessage()와 printStackTrace()를 통해서 이 정보들을 얻을 수 있다. | ||
+ | - printStackTrace() : 예외발생 당시의 호출스택(Call Stack)에 있었던 메서드의 정보와 예외 메시지를 화면에 출력한다. | ||
+ | - getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다. | ||
+ | * [예제 8-12] / | ||
+ | class ExceptionEx12 { | ||
+ | public static void main(String[] args) { | ||
+ | System.out.println(1); | ||
+ | System.out.println(2); | ||
+ | try { | ||
+ | System.out.println(3); | ||
+ | System.out.println(0/ | ||
+ | System.out.println(4); | ||
+ | } catch (ArithmeticException ae) { | ||
+ | ae.printStackTrace(); | ||
+ | System.out.println(" | ||
+ | } | ||
+ | System.out.println(6); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | * 그리고 예외 정보를 파일로 저장할 수도 있다. \\ [예제 8-13] / | ||
+ | import java.io.*; | ||
+ | |||
+ | class ExceptionEx13 { | ||
+ | public static void main(String[] args) { | ||
+ | PrintStream ps = null; | ||
+ | FileOutputStream fos = null; | ||
+ | | ||
+ | try { | ||
+ | fos = new FileOutputStream(" | ||
+ | ps = new PrintStream(fos); | ||
+ | | ||
+ | System.out.println(1); | ||
+ | System.out.println(2); | ||
+ | System.out.println(3); | ||
+ | System.out.println(0/ | ||
+ | System.out.println(4); | ||
+ | } catch (ArithmeticException ae) { | ||
+ | ae.printStackTrace(ps); | ||
+ | ps.println(" | ||
+ | System.out.println(" | ||
+ | } | ||
+ | System.out.println(6); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
===== finally블럭 ===== | ===== finally블럭 ===== | ||
+ | * finally블럭은 try-catch문과 함께 예외의 발생여부와 상관없이 실행되어야할 코드를 포함시킬 목적으로 사용된다. | ||
+ | * try-catch문의 끝에 선택적으로 덧붙여 사용할 수 있으며, try-catch-finally의 순으로 구성된다. <code java> | ||
+ | try { | ||
+ | // 예외가 발생할 가능성이 있는 문장들을 넣는다. | ||
+ | } catch (Exception1 e1) { | ||
+ | // 예외처리를 위한 문장을 적는다. | ||
+ | } finally { | ||
+ | // 예외의 발생여부에 관계없이 항상 수행되어야 하는 문장들을 넣는다. | ||
+ | // finally블럭은 try-catch문의 맨 마지막에 위치해야한다. | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | * [예제 8-15] / | ||
+ | class FinallyTest { | ||
+ | public static void main(String[] args) { | ||
+ | try { | ||
+ | startInstall(); | ||
+ | copyFiles(); | ||
+ | deleteTempFiles(); | ||
+ | } catch (Exception e) { | ||
+ | e.printStackTrace(); | ||
+ | deleteTempFiles(); | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | static void startInstall() { | ||
+ | // 프로그램 설치에 필요한 준비를 하는 코드를 적는다. | ||
+ | } | ||
+ | | ||
+ | static void copyFiles() { | ||
+ | // 파일들을 복사하는 코드를 적는다. | ||
+ | } | ||
+ | | ||
+ | static void deleteTempFiles() { | ||
+ | // 임시파일들을 삭제하는 코드를 적는다. | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | * [예제 8-16] / | ||
+ | class FinallyTest2 { | ||
+ | public static void main(String[] args) { | ||
+ | try { | ||
+ | startInstall(); | ||
+ | copyFiles(); | ||
+ | } catch (Exception e) { | ||
+ | e.printStackTrace(); | ||
+ | } finally { | ||
+ | deleteTempFiles(); | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | static void startInstall() { | ||
+ | // 프로그램 설치에 필요한 준비를 하는 코드를 적는다. | ||
+ | } | ||
+ | | ||
+ | static void copyFiles() { | ||
+ | // 파일들을 복사하는 코드를 적는다. | ||
+ | } | ||
+ | | ||
+ | static void deleteTempFiles() { | ||
+ | // 임시파일들을 삭제하는 코드를 적는다. | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | * 특히, try나 catch 블럭의 문장 수행중에 return을 만나도 finally블럭의 문장들은 수행된다. \\ [예제 8-17] / | ||
+ | class FinallyTest3 { | ||
+ | public static void main(String[] args) { | ||
+ | // method1()은 static메서드이므로 인스턴스 생성없이 직접 호출이 가능하다. | ||
+ | FinallyTest3.method1(); | ||
+ | System.out.println(" | ||
+ | } | ||
+ | | ||
+ | static void method1() { | ||
+ | try { | ||
+ | System.out.println(" | ||
+ | return; | ||
+ | } catch (Exception e) { | ||
+ | e.printStatckTrace(); | ||
+ | } finally { | ||
+ | System.out.println(" | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
===== 메서드에 예외 선언하기 ===== | ===== 메서드에 예외 선언하기 ===== | ||
+ | * 예외를 처리하는 방법에는 지금까지 배워 온 try-catch문을 사용하는 것 이외에, 예외를 메서드에 선언하는 방법이 있다. | ||
+ | * 메서드에 예외를 선언하려면, | ||
+ | void method() throws Exception1, Exception2, ... ExceptionN { | ||
+ | // 메서드의 내용 | ||
+ | } | ||
+ | </ | ||
+ | * 사실, 예외를 메서드의 throws에 명시하는 것은 예외를 처리하는 것이 아니라, 자신(예외가 발생할 가능성이 있는 메서드)을 호출한 메서드에게 예외를 전달하여 예외처리를 떠맡기는 것이다. | ||
+ | |||
+ | * [예제 8-18] / | ||
+ | class Exception18 { | ||
+ | public static void main(String[] args) throws Exception { | ||
+ | method1(); // 같은 클래스내의 static 멤버이므로 객체생성없이 직접 호출가능. | ||
+ | } | ||
+ | | ||
+ | static void method1() throws Exception { | ||
+ | method2(); | ||
+ | } | ||
+ | | ||
+ | static void method2() throws Exception { | ||
+ | throw new Exception(); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | - 예외가 발생했을 때, 모두 3개의 메서드(main, | ||
+ | - 예외가 발생한 곳은 제일 위줄에 있는 method2()라는 것과 | ||
+ | - main메서드가 method1()를, | ||
+ | |||
+ | * 결국, 어디서 든 간에 반드시 try-catch문을 사용해서 예외처리를 해주어야 정상적인 종료를 할 수 있을 것이다. | ||
===== 예외 되던지기 ===== | ===== 예외 되던지기 ===== | ||
+ | * 하나의 예외에 대해서 예외가 발생한 메서드와 호출한 메서드, 양 쪽에서 처리하도록 할 수 있다. | ||
+ | * 이것은 예외를 처리한 수에 인위적으로 다시 발생시키는 방법을 통해서 가능한데, | ||
+ | * [예제 8-23] / | ||
+ | class ExceptionEx23 { | ||
+ | public static void main(String[] args) { | ||
+ | try { | ||
+ | method1(); | ||
+ | } catch (Exception e) { | ||
+ | System.out.println(" | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | static void method1() throws Exception { | ||
+ | try { | ||
+ | throw new Exception(); | ||
+ | } catch (Exception e) { | ||
+ | System.out.println(" | ||
+ | throw e; // 다시 예외를 발생시킨다. | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
===== 사용자정의 예외 만들기 ===== | ===== 사용자정의 예외 만들기 ===== | ||
+ | |||
+ | * 기존의 정의된 예외 클래스 외에 필요에 따라 프로그래머가 새로운 예외 클래스를 정의하여 사용할 수 있다. 보통 Exception클래스로부터 상속받는 클래스를 만들지만, | ||
+ | class MyException extends Exception { | ||
+ | MyException(String msg) { // 문자열을 매개변수로 받는 생성자 | ||
+ | super(msg); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | * 필요하다면 멤버번수를 추가할 수 있다. <code java> | ||
+ | class MyException extends Exception { | ||
+ | // 에러 코드 값을 저장하기 위한 필드를 추가했다. | ||
+ | private final int errorCode = 100; | ||
+ | | ||
+ | MyException(String msg) { // 생성자 | ||
+ | super(msg); | ||
+ | } | ||
+ | | ||
+ | public int getCode() { // 에러 코드를 얻을 수 있는 메서드도 추가했다. | ||
+ | return errorCode; | ||
+ | } | ||
+ | } | ||
+ | </ |