Part 11 예외및입출력 1
이장의내용 p 예외필요성및기본개념을이해한다. p 예외처리방법을이해하고익힌다. p 자신의예외클래스를정의한다. p 예외전파에대해서이해하고활용한다. p Scaer에대해서깊이있게이해하고활용한다. p 다양한입출력스트림을이해하고활용한다. 2
11.1 예외 3
예외 p 예외혹은예외상황 (exceptio) p 예외를만났을때이를효과적으로처리하여계속실행해야한다. Key Poit 예외는프로그램실행중에발생하는비정상적인상황혹은덜심각한에러를의미한다. p 예외예 0 으로나누려는시도 범위를벗어난배열의첨자 지정되었는데찾을수없는파일 정상적으로마칠수없는 I/O 연산의요청 널 (ull) 참조를따라가려는시도 기대하지않는문자입력 4
예외처리가필요한이유 p p p 예외를만났을때이를효과적으로처리하지못하면 프로그램은계속실행하지못하고종료하게된다. 프로그램이예외를만났을때효과적으로대처하지못하면 결과적으로이러한프로그램은신뢰할수없는프로그램이될것이다. 적절한예외처리는 프로그램의안전한실행및신뢰성을위해매우중요하다. p 예제프로그램 GradeIput 표준입력으로부터점수를입력받는프로그램 정수값이입력되면정상적으로동작 잘못된입력이들어오면 extit 메소드에서 IputMismatchExceptio 발생 실행결과 : 이예외를만나면프로그램은더이상진행하지못하고종료 5
6
실행결과 실행결과 ========================================== 점수입력 : 88 점수입력 : $12.99 Exceptio i thread "mai java.util.iputmismatchexceptio at java.util.scaer.throwfor(ukow Source) at java.util.scaer.ext(ukow Source) at java.util.scaer.extit(ukow Source) at java.util.scaer.extit(ukow Source) at GradeIput.mai(GradeIput.java:17) 7
예외정의 p 예외란비정상적인상황을나타내는하나의객체이다. p 예외정의 예외를사용하기위해서는먼저예외를정의하는클래스가있어야한다. p 예외를정의하는클래스분류 (1) API 클래스라이브러리에사전에정의된예외클래스 (2) 사용자가정의하는예외클래스 8
런타임예외 런타임예외 ArithmeticExceptio ArrayIdexOutofBoudsExcep tio NegativeArraySizeExceptio NullPoiterExceptio IputMismatchExceptio 설명 0으로나누는경우에주로발생하는예외상황배열의크기보다큰원소를접근하려고할때발생되는예외배열의크기가음수로된경우에발생하는예외생성되지않은객체를이용해서객체의멤버를접근하는경우에발생하는예외입력값이기대되는데이터타입에부합하지않을때발생되는예외 9
예외클래스 p 예외클래스는 Exceptio 클래스나그하위클래스로부터상속받아정의한다. 일종의클래스이므로생성자, 멤버필드, 메소드등을가질수있다. ew 연산자를이용하여예외객체를만들수있다. 해당예외상황을만나면그예외객체를던짐 (throw) 으로써예외를발생시킬수있다. 예외객체도일등급객체 (first-class object) 로일반객체처럼클래스를이용하여정의되고일반객체처럼사용될수있다. 10
예외클래스계층구조 11
예외클래스정의 : 예 class NegativeIputExceptio exteds Exceptio { private Strig reaso; public NegativeIputExceptio( ) { reaso = " 음수입력 "; } } public Strig tostrig() { retur " 예외 :" + reaso; } 12
11.2 예외처리 13
예외처리는어떻게하는가? p 프로그램실행 정상적인실행부분 예외적인실행부분 p 프로그램이정상적으로실행되다가예외상황을만나면예외가발생 (throw) 되며, 잡아서 (catch), 적절히처리 (hadle) 하여야한다. p 예외처리방법 (1) 예외를무시한다. p 예외가발생한위치를알려주는호출스택트레이스 (call stack trace) 를포함한메시지를출력하고종료된다. (2) 예외를발생한곳에서처리한다. (3) 예외를프로그램의다른지점에서처리한다. 14
예외처리 p 예외처리 try-catch 문 (try-catch statemet) 예외가발생할수있는문장들을 try 블록안에포함시켜야한다. 각 catch 절은서로다른형의예외를처리하는문장들을포함한다. try { 정상코드 } catch ( 예외이름변수이름 ) { 예외처리코드 } catch ( 예외이름변수이름 ) { 예외처리코드 } p 예외가발생하면 예외형과일치하는첫번째 catch 절로제어가넘어가서발생된예외를처리하게된다 15
예외처리 : 예 p 프로그램 GradeIput.java 의 sca.extit( ) 문 try { ewgrade = sca.extit( ); } catch (IputMismatchExceptio x) { } System.out.pritl(x); sca.ext( ); 16
throw 문 p 예외적인상황을만났을때예외를발생시킬수있다. throw 예외객체 p p 예 if (ewgrade < 0) 예 try { throw ew NegativeIputExceptio( ); ewgrade = sca.extit( ); if (ewgrade < 0) throw ew NegativeIputExceptio( ); } catch (IputMismatchExceptio x) { System.out.pritl(x); sca.ext( ); } catch (NegativeIputExceptio x) { } System.out.pritl(x); 17
18
19
100 이상입력처리 p p 다음코드 idex = ewgrade / 10; freq[idex]++; 만약입력점수가 100 점이상이면점수입력 : 100 Exceptio i thread"mai"java.lag.arrayidexoutofboudsexceptio:10 at GradeDist1.mai(GradeDist1.java:25) p 입력이 100 이상인경우를대비하기위해서 try { freq[idex]++; } catch (ArrayIdexOutOfBoudsExceptio x) { } if (ewgrade == 100) freq[9]++; else System.out.pritl(" 예외 :" + ewgrade + " 는범위밖임 "); 20
21
22
fially 절 p try 문은선택문장인 fially 절을포함할수있으며, p fially 절은예외의발생여부에관계없이실행된다. try { 정상코드 } catch ( 예외이름변수이름 ) { 예외처리코드 } catch ( 예외이름변수이름 ) { 예외처리코드 } fially { } 주의 fially 절은예외발생여부와관계없이실행된다. 23
fially 절 p fially 절의효과를알아보기위한코드 Scaer sca = ew Scaer(System.i); try { sca.extit(); } catch (IputMismatchExceptio x) { System.out.pritl(" 다음토큰이정수가아닙니다."); } catch (NoSuchElemetExceptio x) { System.out.pritl(" 입력이없습니다."); } catch (IllegalStateExceptio x) { System.out.pritl(" 스캐너가닫혀있습니다."); } fially { } System.out.pritl(" 하나의정수입력혹은예외발생함."); 24
예외전파 p 예외가발생된메소드내에서처리되지않으면어떻게될까? 그예외는그메소드를호출한호출자 (caller) 메소드에전파된다. 그예외는잡아서처리될때까지호출의역순을따라계속전파된다. 아무메소드도잡아서처리하지않으면결국 mai 메소드까지전파 mai 메소드에서도처리되지않으면결국프로그램은종료 Key Poit 예외가발생된메소드내에서처리되지않으면호출자메소드로전파된다. 25
Propagate1.java 26
Propagate1.java 27
검사예외 / 비검사예외 p 프로그램신뢰성과예외 프로그램실행중에예외로인해갑자기종료하는것은프로그램신뢰성에매우치명적인영향을준다. p Java 컴파일러의예외처리기검사 발생가능한예외들에대해서이를처리할수있는처리기의존재여부를미리검사한다. 그러나모든예외들의처리기존재여부를검사하는것은매우어렵고프로그래머들을너무불편하게만들수있다. 따라서 Java 언어에서는이검사여부에따라예외를두종류로분류한다 28
검사예외 / 비검사예외 p 비검사예외 (uchecked exceptio) RutimeExceptio 로부터상속받는런타임예외에대해서는컴파일러가그처리기존재여부를미리검사하지는않는다. 그러나프로그램의안전한실행을위해서비검사예외도프로그래머의판단에따라예외처리기를작성하는것이좋다. p 검사예외 (checked exceptio) 런타임예외가아닌모든예외들에대해서는컴파일러가그처리기의존재여부를미리검사한다. 검사결과적절하게처리될수없으면다음오류메시지를낼것이다. OOOExceptio must be caught or declared to be throw 29
검사예외 / 비검사예외 Key Poit 런타임예외는비검사예외이고나머지모든예외는검사예외이다. 30
검사예외처리 (1) 해당메소드내에 try-catch 구문을이용하여그예외를처리하는코드를추가한다. (2) 해당메소드내에서처리하지않을검사예외들은메소드헤더에 throws 절을이용하여명시한다. 리턴타입메소드이름 ( 매개변수리스트 ) throws 예외이름리스트 { }... Key Poit 해당메소드내에서처리하지않을검사예외들은메소드머리에 throws 절을이용하여명시하여야한다. 31
Propagate2.java 32
33
11.4 Scaer 34
Scaer p p Scaer 객체 예 입력된스트링을토큰들로분리하며여러메소드들을이용하여토큰들을필요한타입의값들로변환한다. sc = ew Scaer(System.i); it i = sc.extit(); p 예 Scaer sc = ew Scaer(ew File("myNumbers.dat")); while (sc.hasnextit()) { log alog = sc.extit(); } 35
반환타입 메소드이름 설명 Strig ext() 다음한토큰을읽는다. byte extbyte() 다음한바이트를읽는다. double extdouble() 다음 double 부동소수점수를읽는다. float extfloat() 다음부동소숫점수를읽는다. it extit() 다음정수를읽는다. Strig extlie() 다음한줄을읽는다. log extlog() 다음 log 정수를읽는다. short extshort() 다음 short 정수를읽는다. boolea hasnext() 다음한바이트가있으면 true를리턴한다. boolea hasnextbyte() 다음한바이트가있으면 true를리턴한다. boolea hasnextdouble() 다음 double 부동소수점수가있으면 true를리턴한다. boolea hasnextfloat() 다음부동소숫점수가있으면 true를리턴한다. boolea hasnextit() 다음정수가있으면 true를리턴한다. boolea hasnextlie() 다음한줄이있으면 true를리턴한다. boolea hasnextlog() 다음 log 정수가있으면 true 를리턴한다. boolea hasnextshort() 다음 short 정수가있으면 true 를리턴한다. 36
Scaer 사용 p import java.util.scaer; java.util.scaer 패키지에있는 Scaer 클래스를사용하겠다는것을표시 p Scaer sca = ew Scaer(System.i); p iput = sca.extlie(); extlie 메소드를이용하면키보드로부터한줄의문자열을읽어들일수있다. p System.out.pritl(" 입력한데이터 : " + iput ); iput 이참조하고있는문자열을모니터에다음과같이출력한다. 37
38
39
11.5 입출력스트림 40
스트림 p 스트림 (stream) 입력원천 (iput source) 혹은출력목적지 (output destiatio) 를갖는일련의바이트시퀀스를추상화한것 스트림을사용하는이유는입출력장치에독립적인입출력방식을제공하기위해서다. 41
스트림의종류 p 다루는데이터의단위에따라구분 바이트스트림 (byte stream): 바이트단위로입출력하는스트림 문자스트림 (character stream): 문자단위로입출력하는스트림 데이터스트림 (data stream): 데이터타입단위로입출력하는스트림 Key Poit 바이트스트림은바이트단위로입출력하는스트림이고문자스트림은문자단위로입출력하는스트림이며데이터스트림은데이터타입단위로입출력하는스트림이다. 42
바이트스트림 43
바이트스트림 p 바이트스트림 (byte stream) 바이트단위로읽고쓰기위한저수준스트림으로이를이용하여바이트입출력이가능하다. IputStream, OutputStream 추상클래스를상속받아다양한바이트스트림을만들수있다. 가장대표적인바이트스트림은 FileIputStream 과 FileOutputStream 이 44
FileIputStream FileIputStream 의 생성자및메소드 FileIputStream(Strig ame) 역할 이름이 ame 인실제파일을열어 FileIputStream 을만든다. FileIputStream(File file) 파일 file 을열어 FileIputStream 을만든다. it read( ) it read(bytes[] b) 이입력스트림으로부터한바이트를읽어리턴 이입력스트림으로부터 b.legth 개의바이트를읽 어배열 b 에저장하고읽은바이트수를리턴 45
FileOutputStream FileOutputStream 의 생성자및메소드 FileOutputStream(Strig ame) 이름이 ame 인파일을 역할 열어 FileOutputStream 을만든다. FileOutputStream(File file) 파일 file 을열어 FileOutputStream 을만든다. void write(it b) 한바이트 b 를이출력스트림에쓴다. void write(bytes[] b) 배열 b 의 b.legth 개의바이트들을이출력 스트림에쓴다. 46
47
바이트스트림 p 기존스트림에부가적인입출력기능을추가하여제공하는스트림 FilterIputStream(IputStream i) FilterOutputStream(OutputStream out) p 예 : 프린트스트림 (PritStream) FilterOutputtStream 중의하나로여러타입의값을스트링형태로출력가능 p 표준입출력을위해다음과같은세종류의표준스트림 표준입력 System.i: 키보드부터표준입력을위한입력스트림 표준출력 System.out: 모니터로표준출력을위한프린트스트림 표준오류 System.err: 모니터로오류메시지출력을위한프린트스트림 48
문자스트림 49
문자스트림 p 문자스트림 2 바이트로표현되는유니코드 (uicode) 문자단위의입출력을위한스트림 Reader, Writer 클래스는추상클래스이며그하위클래스들이문자스트림임. FileReader 와 FileWriter 역시일종의문자스트림으로텍스트파일로부터문자단위입출력을할수있음. 50
FileReader FileReader의생성자및메소드 FileReader(Strig ame) FileReader(File file) 역할 명시된파일을기초로하여입력문자스트림을 만든다. it read( ) 이문자스트림에서한문자를읽어리턴한다. it read(char[] cbuf, it off, it le) 이문자스트림에서 le 개의문자를읽어배열 cbuf 의인덱스 off 에서부터시작하여저장한다. 읽은문자수를리턴한다. 51
FileWriter FileWriter의생성자및메소드 FileWriter(Strig ame) FileWriter(File file) 역할 명시된파일을기초로하여출력문자스 트림을만든다. void write(it c) 한문자 c 를이문자스트림에쓴다. void write(char[] cbuf, it off, it le) 배열 cbuf 의인덱스 off 에서부터시작하 여 le 개의문자를이문자스트림에쓴다. 52
IputStreamReader(Writer) p IputStreamReader 와 OutputStreamWriter 파일뿐만아니라임의의바이트스트림으로부터문자스트림을만들어문자단위입출력을할수있다. 생성자 IputStreamReader(IputStream i) OutputStreamWriter(OutputStream out) FileReader 및 FileWriter 와똑같은메소드를이용가능 p 버퍼를이용하여스트림내부정보를관리하는고수준문자스트림 BufferedReader(Reader i) BufferedWriter(Writer out) 53
54
DataIputStream DataIputStream의생성자및메소드 DataIputStream(IputStre am i) char readchar( ) it readit( ) log readlog( ) float readfloat( ) double readdouble( ) boolea readboolea( ) 역할 IputStream i을기초로하여 DataIputStream을만듬한문자를읽어서리턴정수 (4 바이트 ) 를읽어서리턴 log 정수 (8 바이트 ) 를읽어서리턴부동소수점수 (4 바이트 ) 를읽어서리턴 double 부동소수점수 (8 바이트 ) 를읽어서리턴한바이트를읽어 0이면 false를 0이아니면 true 를리턴 55
DataOutputStream DataOutputStream의생성자및메소드 DataOutputStream(OutputStre am out) 역할 OutputStream out 을기초로하여 DataOutputStream 을만든다. void writechar(it v) 한문자를쓴다. void writeit(it v) 한정수 (4 바이트 ) 값을쓴다. void writelog(log v) log 정수 (8 바이트 ) 값을쓴다. void writefloat(float v) 부동소수점수 (4 바이트 ) 값을쓴다. void writedouble(double v) double 부동소수점수 (8 바이트 ) 값을쓴다. void writeboolea(boolea v) 한 boolea 값을쓴다. 56
CityIput.java 57
CityIput.java 58
CityData.java 59
CityData.java 60
11.6 GUI 예제 : 파일뷰어프로그램 61
파일뷰어프로그램 p 사용자가선택한파일의내용을보여주는 GUI 프로그램작성 p 파일선택자 (FileChooser) 보여줄파일을선택하기위한파일선택자 (FileChooser) JFileChooser는파일을선택하는데사용되는 GUI 컴포넌트 JFileChooser filechooser = ew JFileChooser(); p 텍스트영역 (TextArea) 선택된파일내용을보여주는텍스트영역 (TextArea) JTextArea는파일내용을보여주는데사용되는 GUI 컴포넌트 JTextArea textarea = ew JTextArea(25, 80); 62
파일선택자, 텍스트영역 63
64
65
66
Key Poit 67
Key Poit p p p 예외는프로그램실행중에발생하는비정상적인상황혹은덜심각한에러를의미한다. 발생된예외는 try-catch 문에의해처리되어야하고처리되지않으면그프로그램은종료한다. 예외가발생된메소드내에서처리되지않으면호출자메소드로전파된다. p 런타임예외는비검사예외이고나머지모든예외는검사예외이다. p p 메소드내에서처리될수없는검사예외들은메소드머리에 throws 절을이용하여명시하여야한다. 바이트스트림은바이트단위로입출력하는스트림이고문자스트림은문자단위로입출력하는스트림이며데이터스트림은데이터타입단위로입출력하는스트림이다 68
프로그래밍실습 69
프로그래밍실습 1 1. 점수분포예외처리 7 장의프로그래밍실습 1 을 0 부터 100 점이외의점수가들어왔을때적절하게처리할수있도록수정하시오. 70
프로그래밍실습 2 2. 간단한에디터 프로그램 11.12 의 ViewFile 프로그램을파일닫기버튼과파일저장버튼을포함하는간단한에디터프로그램으로확장하시오. 파일닫기버튼을누르면보여준파일내용은사라져야한다. 파일저장버튼을누르면현재보여주고있는파일내용이저장되어야한다. 71