JAVA 프로그래밍 11. 예외처리 한동일 학습목표 To learn how to throw exceptions To be able to design your own exception classes To understand d the difference between checked and unchecked exceptions To learn how to catch exceptions To know when and where to catch an exception 2/35
개요 예외 (exception) 실행시간에발생하는에러 (run-time error) 프로그램의비정상적인종료 잘못된실행결과 예외처리 (exception handling) 기대되지않은상황에대해예외를발생 야기된예외를적절히처리 (exception handler) 예외처리를위한방법을언어시스템에서제공 응용프로그램의신뢰성 (reliability) 을높임. 예외검사와처리를위한프로그램코드를소스에깔끔하게삽입 3/35 Throwable 클래스의계층구조 Throwable Error LinkageError ThreadDeath Java.lang VirtualMachineError RuntimeException NegativeArraySizeException NullPointerException ArrayStoreException IndexOutOfBoundException systemdefined exception Exception CloneNotSupportedException IllegalAccessException InstantiationException InterruptedException EOFException programmer- defined exception NoSuchMethodException FileNotFoundException IOException InterruptedIOException t ti Throwable 클래스에는예외가일어난상황을설명하는메시지들을포함 4/35
예외의종류 예외의종류 System-defined exception(predefined exception) Error 클래스, RuntimeException 클래스 Programmer-defined exception Error 클래스 정상적인응용프로그램에서는수용할수없는심각한에러 Exception 클래스 정상적인응용프로그램의실행에서발생가능한예외를의미 프로그래머에의해처리가능 5/35 예외의종류 시스템정의예외 (system-defined d exception) 프로그램의부당한실행으로인하여시스템에의해묵시적발 생하는예외 Error 와 RuntimeException 클래스로부터확장된예외 더이상프로그램의실행을지속할수없을때자바시스템에의해자동적으로생성 야기된예외에대한예외처리기의유무를컴파일러가검사하지않음 ===> unchecked exception 시스템예외의종류 ArithmeticException, IndexOutOfBoundsException, NegativeArraySizeException, 6/35
예외의종류 IndexOutOfBoundsException : 배열, 스트링, 벡터등과같이인덱스를사용하는객체에서인덱스의범위가벗어날때발생 ArrayStoreException : 배열의원소에잘못된형의객체를배정하였을때발생 NegativeArraySizeException : 배열의크기를음수로지정하였을때발생 NullPointerException : null 을사용하여객체를참조할때발생 7/35 예외의종류 프로그래머정의예외 예 : 프로그래머가필요에의해정의 Exception 클래스의서브클래스 프로그래머에의해의도적으로발생 발생한예외에대한예외처리기가존재하는지컴파일러에의해검사, 예외처리기가없으면에러 checked exception class UserException extends Exception { 8/35
예외상황의생성 예외도하나의객체로취급 따라서, 먼저예외를위한클래스를정의해야함. 예외클래스 모든예외는형 (type) (yp 이 Throwable 클래스또는그의서브클래스들 중에하나로부터확장된클래스의객체 일반적으로프로그래머는 Throwable의서브클래스인 Exception 을확장하여새로운예외클래스를만들어사용 class UserErr extends Exception { class UserClass { UserErr x = new UserErr(); //... if (val < 1) throw x; 9/35 예외상황의생성 예외에관련된메시지를스트링형태로예외객체에담아전달 class UserErr extends Exception { UserErr(String s) { super(s); // constructor class UserClass { //... if (val < 1) throw new UserErr("user exception throw message"); 10/35
throw 문과 throws 절 예외발생 시스템정의예외 시스템에의해묵시적으로발생 프로그래머정의예외 프로그래머가명시적으로발생 throw 구문 시스템정의예외나프로그래머정의예외를명시적으로발생시키는구문. 구문형태 : Throwable 클래스혹은그의서브클래스 throw ThrowableObject; 11/35 throw 문과 throws 절 throw 구문 프로그래머에의해의도적으로예외를발생시킬때사용 프로그래머가정의한예외뿐만아니라시스템정의예외도발생가능 for (int i=0; i<10; i++) { ch=(char)system.in.read(); if (!Character.isDigit(ch)) // 읽은값이숫자가아니면예외발생 throw new NoDigitException(); ite ti else sum += ch -'0'; sum += ch 0 ; // 숫자로변환하여 sum 에합산 예외를발생시킴 12/35
throw 문과 throws 절 아래코드의실행결과는? class ThrowStatement extends Exception { public static void exp(int ptr) { if (ptr == 0) throw new NullPointerException(); public static void main(string[ ] args) { int i = 1; 0; ThrowStatement.exp(i); // static method java.lang.nullpointerexception Press at ThrowStatement.exp(ThrowStatement.java:4) any key to continue at ThrowStatement.main(ThrowStatement.java:8) main(throwstatement 13/35 throw 문과 throws 절 throws 절 프로그래머정의예외가발생하는경우, 예외처리기를갖고있지않으면메소드선언부분에명시 선언형태 : modifiers_ and_ returntype methodname(params) throws e1,...,ek { 명시해주는이유 : 메소드가정상적인복귀외에예외에의해복귀할수있다는것을알려줌 시스템정의예외는명시해주지않음 14/35
throw 문과 throws 절 throws 절사용예 예외가발생한메소드에서예외처리를하지않고 (try / catch 문이없는경우 ), 호출한상위클래스로예외처리를넘김 method_1( ) { method_2( ) throws Exception {.. method_2( ) ; method_3 ( );.... catch (Exception e) {.. method_3( ) throws Exception {.. 예외가발생한부분.. 15/35 try, catch, finally 문 try-catch-finally thfi 구문 예외를검사하고처리해주는문장 구문형태 : // try 블록 catch (ExceptionType1 identifier) { // catch 블록 catch (ExceptionType2 identifier) { // catch 블록 finally { // finally 블록 try 블록 --- 예외가검사되는블록 catch 블록 --- 예외가처리되는블록 Finally 블록 --- 예외의발생유무와상관없이처리됨 16/35
try, catch, finally 문 try / catch 에의한예외처리 예외처리가필요한메소드에서 try/catch 구문이없거나 throws 절이없는경우에러메시지발생 예외가발생할만한코드 catch ( 해당 Exception e ) { 예외처리를위한루틴 int a[ ] = new int [4]; a[5] = 10; System.out.println( 값은 + a[5]); catch (Exception e) { System.out.println( 에러입니다 ); 17/35 try, catch, finally 문 다중 catch 구문 여러개의 try/catch 구문을 블록한개와 catch { 블록여러개로사용 다중 catch 문을사용시하위예외를먼저 catch 하도록배치할것 예외가발생하는코드들을한곳에모은다 catch (.. ) { catch (.. ) { catch (.. ) { reader = new FileReader( file_name); reader.read(buffer, 0, 100); String str = new String(buffer); System.out.println( 읽은것 + str); reader.close( ); catch ( FileNotFoundException e ) {.. catch ( IOException e ) {.. catch ( Exception e ) {.. 18/35
Throwable 클래스의계층구조 Throwable Error LinkageError ThreadDeath Java.lang VirtualMachineError RuntimeException NegativeArraySizeException NullPointerException ArrayStoreException IndexOutOfBoundException systemdefined exception Exception CloneNotSupportedException IllegalAccessException InstantiationException InterruptedException EOFException programmer- defined exception NoSuchMethodException FileNotFoundException IOException InterruptedIOException t ti Throwable 클래스에는예외가일어난상황을설명하는메시지들을포함 19/35 try, catch, finally 문 try / catch / finally 구문 예외발생시예외와관계없이반드시수행해야하는루틴이있는경우 finally 구문사용 int a[ ] = new int [2]; a[4]; catch ( ArrayIndexOutOfBoundsException e ) { System.out.println ( exception : + e.getmessage( )); e.printstacktrace( ); finally { System.out.println( 이코드는예외와상관없이반드시실행됨 ); 20/35
try, catch, finally 문 예외처리기의실행순서 1. try 블록내에서예외가검사되고또는명시적으로예외가발생하면, 2. 해당하는 catch 블록을찾아처리하고,( 순서중요 ) 3. 마지막으로 finally 블록을실행한다.( 반드시실행 ) Default 예외처리기 시스템정의예외가발생됐는데도불구하고프로그래머가처리하지않을때처리됨 단순히에러에대한메시지를출력하고프로그램을종료하는기능 21/35 예외의전파 호출한메소드로예외를전파 (propagation) 하여특정메소드에서모아처리 예외처리코드의분산을막을수있음 엉성하게예외를직접처리하는것보다검사된예외를선언하 는것이더좋은방법 예외는가급적빨리던지고늦게받아서처리하는것이좋은방법 예외전파순서 예외를처리하는 catch 블록이없으면, 호출한메소드로예외 를전파 예외처리기를찾을때까지의모든실행은무시 22/35
예외의전파 public class Propagate { void orange() { int m = 25, i = 0; i = m / i; void apple() { orange(); public static void main(string[] args) { Propagate p = new Propagate(); p.apple(); ArithmeticException 발생 Default 예외처리기에의한출력 java.lang.arithmeticexception: / by zero at Propagate.orange(Propagate.java:4) at Propagate.apple(Propagate.java:7) pp p g at Propagate.main(Propagate.java:11) 23/35 예외의전파 예외발생가능성에대한명시 시스템정의예외 예외의발생가능성을알릴필요없음 프로그래머정의예외 해당메소드에서처리하지않을경우, 예외의종류를알려야함 throws 절사용 public void methoda() throws MyException { // if (someerrcondition()) throw new MyException(); // 24/35
예외처리의요약 예외처리목적 별개의통로를제공하여더욱안전한프로그램을작성 예외처리의상황 에러를수정하고예외를발생시킨메소드의재호출이필요한경우 메소드의재호출없이에러를수정하고실행을계속하는경우 메소드가그의실행결과를포기하는대신에대안적인결과가필요한경우 발생한예외를적절히처리한후, 호출자에게동일예외또는다른예외를재발생시킬필요가있는경우 예외가일어났을때프로그램을종료하려는경우 25/35 파일입력예제 강의홈페이지의 Data 폴더참고 DataSetTester.java 예외의처리 적당한오류메시지출력 올바른파일입력을위한기회제공 26/35
파일입력예제 Scanner in = new Scanner(System.in); DataSetReader reader = new DataSetReader(); boolean done = false; while (!done){ System.out.println("Please enter the file name: "); String filename = in.next(); double[] data = reader.readfile(filename); double sum = 0; for (double d : data) sum = sum + d; System.out.println("The sum is " + sum); done = true; catch (FileNotFoundException exception) { System.out.println("File not found."); catch (BadDataException exception) { System.out.println ("Bad data: " + exception.getmessage()); catch (IOException exception) { exception.printstacktrace(); 27/35 파일입력예제 DataSetReader.java 의 readfile() 메소드 Scanner 객체구성 readdata() 메소드호출 문제발생시예외를메소드호출한곳으로넘김 그밖에예외처리에대해서는전혀무관심 예외발생시에도 file close 동작을보장함 28/35
파일입력예제 public double[] readfile(string filename) throws IOException, BadDataException // FileNotFoundException is an IOException { FileReader reader = new FileReader(filename); Scanner in = new Scanner(reader); readdata(in); finally { reader.close(); return data; 29/35 파일입력예제 DataSetReader.java 의 readdata() 메소드 데이터의개수를입력 배열구성 각데이터값에대한 readvalue() 메소드호출 두개의오류를검사 파일이정수로시작되지않는경우 파일에추가적인데이터가남아있는경우 예외에대한처리시도없음 예외발생시호출자에게넘김 30/35
파일입력예제 private void readdata(scanner in) throws BadDataException { if (!in.hasnextint()) t()) throw new BadDataException("Length expected"); int numberofvalues = in.nextint(); data = new double[numberofvalues]; for (int i = 0; i < numberofvalues; i++) readvalue(in, i); if (in.hasnext()) throw new BadDataException("End of file expected"); 31/35 파일입력예제 DataSetReader.java 의 readvalue() 메소드 private void readvalue(scanner in, int i) throws BadDataException { if (!in.hasnextdouble()) throw new BadDataException("Data value expected"); data[i] = in.nextdouble(); BadDataExcetion.java public class BadDataException extends Exception { public BadDataException() { public BadDataException(String message) { super(message); 32/35
파일입력예제 bad3.dat 입력시처리과정 DataSetTester.main calls DataSetReader.readFile readfile calls readdata readdata calls readvalue readvalue doesn't find expected value and throws BadDataException readvalue has no handler for exception and terminates readdata has no handler for exception and terminates readfile has no handler for exception and terminates after executing finally clause DataSetTester.main has handler for BadDataException; handler prints a message, and user is given another chance to enter file name 33/35 [ 실습 1] 파일입력 강의홈페이지 Data 폴더내의 DataSetTester.java code를이해하라. ( 교재 669 페이지참고 ) 다양한파일입력을통한실행결과를확인하고코드이해의완성도를높여라. 아래질문에대한답을도출하라. DataSetReader.readFile() 메소드에예외처리기를두지않은이유는? 존재는하지만내용이없는파일을읽어들였을때의실행의흐름은? 34/35
[ 실습 2] 줄번호삽입 강의홈페이지 LineNumber 폴더내의 LineNumberer.java code를이해하라. 다양한파일입력을통한실행결과를확인하라. 입력된파일의라인수를출력하도록코드를수정하라. 35/35