580 likes | 593 Views
10 장. 예외 (Exceptions). 예외 (Exceptions). 예외처리는 객체지향적 설계에 있어 중요한 특성이다 . 10 장은 다음에 초점을 두고 있다 : 예외의 목적 예외 메시지 try-catch 문 예외의 전파 예외 클래스 계층 GUI 단축 기호와 도구 팁 추가 GUI 컴포넌트와 컨테이너. 개요. 예외 처리 try-catch 문 예외 전파 예외 클래스 입출력 예외 도구 팁과 단축 기호 콤보 박스 스크롤 페인과 분할 페인. 예외 (Exceptions).
E N D
10장 예외 (Exceptions)
예외(Exceptions) • 예외처리는 객체지향적 설계에 있어 중요한 특성이다. • 10장은 다음에 초점을 두고 있다: • 예외의 목적 • 예외 메시지 • try-catch 문 • 예외의 전파 • 예외 클래스 계층 • GUI 단축 기호와 도구 팁 • 추가 GUI 컴포넌트와 컨테이너
개요 예외 처리 try-catch 문 예외 전파 예외 클래스 입출력 예외 도구 팁과 단축 기호 콤보 박스 스크롤 페인과 분할 페인
예외(Exceptions) • 예외란 통상적이지 않거나 잘못된 상황을 정의하는 하나의 객체이다. • 예외는 프로그램에 의하여 실행시간에 발생(thrown)되며, 원한다면 잡아서(catch), 적절히 처리할(handle)수 있다. • 프로그램은 정상적인 실행부분과 예외 실행부분으로 분리될 수 있다.
예외처리(Exception Handling) • 프로그램은 다음 세가지 방법중의 하나로 예외를 처리할 수 있다: • 예외를 무시한다. • 예외를 발생한 곳에서 처리한다. • 예외를 프로그램의 다른 지점에서 처리할 수 있다. • 예외가 처리되는 방법은 설계의 중요한 고려사항이다.
예외처리 • 만약에 예외가 프로그램에 의하여 무시되면 그 프로그램은 적절한 메시지를 출력하고 종료된다. • 그 메시지는 예외가 발생한 위치를 알려주는 호출 스택 트레이스(call stack trace)를 포함한다. • 호출 스택 트레이스는 예외가 발생된 메쏘드와 문장 번호를 함께 보여준다. • 예제: Zero.java
Zero.java // Demonstrates an uncaught exception. public class Zero { // Deliberately divides by zero to produce an exception. public static void main (String[] args) { int numerator = 10; int denominator = 0; System.out.println (numerator / denominator); System.out.println ("This text will not be printed."); } } <Output> Exception in thread “main” java.lang.ArithmeticException: / by zero at Zero.main(Zero.java:17)
개요 예외 처리 try-catch 문 예외 전파 예외 클래스 입출력 예외 도구 팁과 단축 기호 콤보 박스 스크롤 페인과 분할 페인
try-catch 문 • 발생된 예외를 처리하기 위해서는 예외가 발생이 일어나는 문장을 try 블록 안에 포함시켜야 한다. • try 블록 다음에는 예외를 처리할 수 있는 문장 코드가 포함된 하나 이상의 catch 절이 따라오게 된다. • 각 catch 절은 서로 다른 형의 예외를 처리하는 문장들을 포함한다. • 예외처리는 예외 형과 일치하는 첫 번째 catch 절에서 이루어진다. • 예제: ProductCodes.java
ProductCodes.java // Demonstrates the use of a try-catch block. import java.util.Scanner; public class ProductCodes { // Counts the number of product codes that are entered with a // zone of R and and district greater than 2000. public static void main (String[] args) { String code; char zone; int district, valid = 0, banned = 0; Scanner scan = new Scanner (System.in); System.out.print ("Enter product code (XXX to quit): "); code = scan.nextLine();
ProductCodes.java while (!code.equals ("XXX")) { try { zone = code.charAt(9); district = Integer.parseInt(code.substring(3, 7)); valid++; if (zone == 'R' && district > 2000) banned++; } catch (StringIndexOutOfBoundsException exception) { System.out.println ("Improper code length: " + code); } catch (NumberFormatException exception) { System.out.println ("District is not numeric: " + code); } System.out.print ("Enter product code (XXX to quit): "); code = scan.nextLine(); } System.out.println ("# of valid codes entered: " + valid); System.out.println ("# of banned codes entered: " + banned); } }
ProductCodes.java <실행 결과> Enter product code (XXX to quit): TRV2475A5R-14 Enter product code (XXX to quit): TRD1704A7R-12 Enter product code (XXX to quit): TRL2k74A5R-11 District is not numeric: TRL2k74A5R-11 Enter product code (XXX to quit): TRQ2949A6M-04 Enter product code (XXX to quit): TRV2105A2 Improper code length: TRV2105A2 Enter product code (XXX to quit): TRQ2778A7R-19 Enter product code (XXX to quit): XXX # of valid codes entered: 4 # of banned codes entered: 2
finally절 • try 문은 선택문장인 finally 절을 포함할 수 있으며, 예외의 발생 여부에 관계없이 실행되는 절이다. • finally 절은 아무런 예외가 발생되지 않은 경우 try 블록이 종료된 후 실행된다. • 또한 예외가 발생된 경우에는 catch 절이 종료된 후에 finally 문장이 실행된다.
개요 예외 처리 try-catch 문 예외 전파 예외 클래스 입출력 예외 도구 팁과 단축 기호 콤보 박스 스크롤 페인과 분할 페인
예외 전파(Exception Propagation) • 예외가 발생된 곳에서 적절한 처리가 이루어지지 않으면 예외는 상위 레벨에서 처리될 수 있다. • 예외는 처리 계층을 호출하는 메쏘드를 통하여 예외가 잡혀 처리될 때까지, 또는 예외가 최상위 레벨에 도달할 때 까지 상위 단계로 전파된다. • 바깥 레벨에서 예외를 잡기 위해서는 예외를 발생시키는 메쏘드가 그 예외를 다룰 catch 절을 가진 try 블록 내부에서 호출되어야만 한다. • 예제: Propagation.javaExceptionScope.java
Propagation.java // Demonstrates exception propagation. public class Propagation { // Invokes the level1 method to begin the exception demonstration. static public void main (String[] args) { ExceptionScope demo = new ExceptionScope(); System.out.println("Program beginning."); demo.level1(); System.out.println("Program ending."); } }
public class ExceptionScope { // Catches and handles the exception that is thrown in level3. public void level1() { System.out.println("Level 1 beginning."); try { level2(); } catch (ArithmeticException problem) { System.out.println (); System.out.println ("The exception message is: " + problem.getMessage()); System.out.println (); System.out.println ("The call stack trace:"); problem.printStackTrace(); System.out.println (); } System.out.println("Level 1 ending."); } ExceptionScope.java
ExceptionScope.java cont’ // Serves as an intermediate level. The exception propagates // through this method back to level1. public void level2() { System.out.println("Level 2 beginning."); level3 (); System.out.println("Level 2 ending."); } // Performs a calculation to produce an exception. It is not // caught and handled at this level. public void level3 () { int numerator = 10, denominator = 0; System.out.println("Level 3 beginning."); int result = numerator / denominator; System.out.println("Level 3 ending."); } }
실행 결과 Program beginning. Level 1 beginning. Level 2 beginning. Level 3 beginning. The exception message is: / by zero The call stack trace: java.lang.ArithmeticException: / by zero at ExceptionScope.level3(ExceptionScope.java:54) at ExceptionScope.level2(ExceptionScope.java:41) at ExceptionScope.level1(ExceptionScope.java:18) at Propagation.main(Propagation.java:17) Level 1 ending. Program ending.
개요 예외 처리 try-catch 문 예외 전파 예외 클래스 입출력 예외 도구 팁과 단축 기호 콤보 박스 스크롤 페인과 분할 페인
예외 클래스와 throw문 • 프로그래머는 적절한 클래스를 확장(extend)해서 예외를 정의할 수 있다. • (사용자가 정의한) 예외는 throw 문을 이용해서 발생시킬 수 있다. • 예제: CreatingExceptions.javaOutOfRangeException.java • 보통 throw 문은 예외가 발생되었는지 확인하기 위하여 조건을 평가하는 if 문 안에 중첩된다.
CreatingExceptions.java // Demonstrates the ability to define an exception via inheritance. import java.util.Scanner; public class CreatingExceptions { // Creates an exception object and possibly throws it. public static void main (String[] args) throws OutOfRangeException { final int MIN = 25, MAX = 40; Scanner scan = new Scanner (System.in); OutOfRangeException problem = new OutOfRangeException ("Input value is out of range."); System.out.print ("Enter an integer value between " + MIN + " and " + MAX + ", inclusive: "); int value = scan.nextInt(); // Determine if the exception should be thrown if (value < MIN || value > MAX) throw problem; System.out.println ("End of main method."); // may never reach } }
OutOfRangeException.java // Represents an exceptional condition in which a value is out of // some particular range. public class OutOfRangeException extends Exception { // Sets up the exception object with a particular message. OutOfRangeException (String message) { super (message); } } 실행 결과 Enter an integer value between 25 and 40, inclusive: 69 Exception in thread "main" OutOfRangeException: Input value is out of range. at CreatingExceptions.main(CreatingExceptions.java:20)
검사 예외(Checked Exceptions) • 예외는 검사 예외(checked exception)와 비검사 예외(unchecked exception)로 나뉜다. • 컴파일러는 검사 예외가 아래 방법 중 하나로 적절하게 처리되지 않으면 그것에 대하여 지적하게 된다. • 예외에 대한 catch • 메쏘드 헤딩에서 throws 표시 • 비검사 예외는 명시적인 처리를 필요로 하지 않는 예외를 말한다. • 자바에서 유일한 비검사 예외는 RuntimeException 및 그 자손 클래스 타입의 객체들이다. • RuntimeException 자손: ArithmeticException, ClassCastException, IndexOutOfBoundsException, NullPointerException, ...
개요 예외 처리 try-catch 문 예외 전파 예외 클래스 입출력 예외 도구 팁과 단축 기호 콤보 박스 스크롤 페인과 분할 페인
I/O 예외 • 스트림이란 발생지(source)에서 목적지(destination)로 전달되는 byte 열을 말한다. • 프로그램에서는 입력 스트림에서 정보를 읽고 출력 스트림으로 정보를 쓴다. • 프로그램에서는 한번에 여러 개의 스트림을 관리할 수 있다. • java.io 패키지는 여러 다른 용도의 스트림을 정의하는데 사용할 수 있는 다양한 클래스를 포함하고 있다. • java.io 패키지의 클래스는 입력 스트림 클래스들과 출력 스트림 클래스들로 나뉜다.
표준 I/O • 표준 I/O 스트림의 세가지 종류 • 표준 입력–System.in로 정의됨 : 키보드 입력 • 표준 출력–System.out로 정의됨 : 특정 윈도우에 출력 • 표준 오류–System.err로 정의됨 : 오류 메시지 출력 • println()메쏘드를 실행시키기 위해서는 System.out을 사용한다.
표준 입력 스트림 • 키보드 객체를 사용하여 다음과 같이 입력 스트림 객체를 선언한다: InputStreamReader isr = new InputStreamReader (System.in) BufferedReader stdin = new BufferedReader (isr); • InputStreamReader객체는 원본 바이트 스트림을 문자 스트림으로 변환한다. • BufferedReader객체는 readLine() 메쏘드를 사용하여 문장 단위로 입력을 받을 수 있게 해준다.
텍스트 파일 • 정보는 I/O 스트림을 선언하고 사용하는 텍스트 파일로부터 입력되거나 출력된다. • FileReader클래스는 문자 데이터를 포함하는 입력 파일을 표현하는 클래스이다. • FileWriter클래스는 텍스트 출력 파일을 표현하는 클래스이다. • 예제: TestData.java
TestData.java // Demonstrates I/O exceptions and // the use of a character file output stream. import java.util.Random; import java.io.*; public class TestData { // Creates a file of test data that consists of ten lines each // containing ten integer values in the range 10 to 99. public static void main (String[] args) throws IOException { final int MAX = 10; int value; String file = "test.dat"; Random rand = new Random(); FileWriter fw = new FileWriter (file); BufferedWriter bw = new BufferedWriter (fw); PrintWriter outFile = new PrintWriter (bw);
for (int line=1; line <= MAX; line++) { for (int num=1; num <= MAX; num++) { value = rand.nextInt (90) + 10; outFile.print (value + " "); } outFile.println (); } outFile.close(); System.out.println ("Output file has been created: " + file); } } TestData.javacont’ <test.dat> 88 90 20 85 95 14 69 62 48 13 94 66 56 10 70 90 88 74 57 51 28 96 87 79 43 97 53 76 20 45 95 64 99 57 52 93 45 12 26 13 28 11 69 39 71 82 66 87 48 85 75 53 29 34 36 83 26 55 80 90 29 94 38 14 14 55 79 28 39 76 83 97 53 75 72 85 82 22 32 96 28 75 62 62 91 32 57 33 31 94 58 68 57 39 67 50 27 56 95 55 <Output> Output file has been created: test.dat
개요 예외 처리 try-catch 문 예외 전파 예외 클래스 입출력 예외 도구 팁과 단축 기호 콤보 박스 스크롤 페인과 분할 페인
도구 팁과 단축 기호 • 도구 팁(tool tip)은 Swing 컴포넌트의 setToolTipText() 메쏘드를 사용하여 지정할 수 있다. JButton button = new JButton(“Compute”); button.setToolTipText(“Calculates the area under the curve”); • 단축 기호(mnemonic)란 마우스를 사용하는 대신 키보드를 사용하여 버튼 누름이나 메뉴 선택을 할 수 있게 해주는 문자이다. • 예제: LightBulb.javaLightBulbPanel.javaLightBulbControl.java
LightBulb.java public class LightBulb { public static void main (String[] args) { JFrame frame = new JFrame ("Light Bulb"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); LightBulbPanel bulb = new LightBulbPanel(); LightBulbControls controls = new LightBulbControls (bulb); JPanel panel = new JPanel(); panel.setBackground (Color.black); panel.setLayout (new BoxLayout(panel, BoxLayout.Y_AXIS)); panel.add (Box.createRigidArea (new Dimension (0, 20))); panel.add (bulb); panel.add (Box.createRigidArea (new Dimension (0, 10))); panel.add (controls); panel.add (Box.createRigidArea (new Dimension (0, 10))); frame.getContentPane().add(panel); frame.pack(); frame.setVisible(true); } }
LightBulbPanel.java 1/2 public class LightBulbPanel extends JPanel { private boolean on; private ImageIcon lightOn, lightOff; private JLabel imageLabel; public LightBulbPanel() { lightOn = new ImageIcon ("lightBulbOn.gif"); lightOff = new ImageIcon ("lightBulbOff.gif"); setBackground (Color.black); on = true; imageLabel = new JLabel (lightOff); add (imageLabel); }
LightBulbPanel.java 2/2 public void paintComponent (Graphics page) { super.paintComponent(page); if (on) imageLabel.setIcon (lightOn); else imageLabel.setIcon (lightOff); } // Sets the status of the light bulb. public void setOn (boolean lightBulbOn) { on = lightBulbOn; } }
LightBulbControl.java 1/3 import javax.swing.*; import java.awt.*; import java.awt.event.*; public class LightBulbControls extends JPanel { private LightBulbPanel bulb; private JButton onButton, offButton; public LightBulbControls (LightBulbPanel bulbPanel) { … } private class OnListener implements ActionListener { … } private class OffListener implements ActionListener { … } }
LightBulbControl.java 2/3 public LightBulbControls (LightBulbPanel bulbPanel) { bulb = bulbPanel; onButton = new JButton ("On"); onButton.setEnabled (false); onButton.setMnemonic ('n'); onButton.setToolTipText ("Turn it on!"); onButton.addActionListener (new OnListener()); offButton = new JButton ("Off"); offButton.setEnabled (true); offButton.setMnemonic ('f'); offButton.setToolTipText ("Turn it off!"); offButton.addActionListener (new OffListener()); setBackground (Color.black); add (onButton); add (offButton); }
LightBulbControl.java 3/3 private class OnListener implements ActionListener { public void actionPerformed (ActionEvent event) { bulb.setOn (true); onButton.setEnabled (false); offButton.setEnabled (true); bulb.repaint(); } } private class OffListener implements ActionListener { public void actionPerformed (ActionEvent event) { bulb.setOn (false); onButton.setEnabled (true); offButton.setEnabled (false); bulb.repaint(); } }
개요 예외 처리 try-catch 문 예외 전파 예외 클래스 입출력 예외 도구 팁과 단축 기호 콤보 박스 스크롤 페인과 분할 페인
콤보 박스 • 콤보 박스(combo box)는 사용자가 드롭다운 메뉴로부터 여러 옵션들 중 하나를 선택하게 해준다. • 콤보 박스는 편집가능(editable), 또는 편집불능(uneditable) 이 될 수 있다. • JukeBox 예제 프로그램 • 콤보 박스에서 연주할 노래를 선택한 다음 play 버튼을 누르면 연주를 시작한다. • JukeBox.java • JukeBoxControls.java
JukeBox.java // Demonstrates the use of a combo box. import javax.swing.*; public class JukeBox { public static void main (String[] args) { JFrame frame = new JFrame ("Java Juke Box"); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); JukeBoxControls controlPanel = new JukeBoxControls(); frame.getContentPane().add(controlPanel); frame.pack(); frame.setVisible(true); } }
JukeBoxControls.java 1/6 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.applet.AudioClip; import java.net.URL; public class JukeBoxControls extends Jpanel { private JComboBox musicCombo; private JButton stopButton, playButton; private AudioClip[] music; private AudioClip current; public JukeBoxControls() { … } private class ComboListener implements ActionListener { … } private class ButtonListener implements ActionListener { … } }
JukeBoxControls.java 2/6 public JukeBoxControls() { URL url1, url2, url3, url4, url5, url6; url1 = url2 = url3 = url4 = url5 = url6 = null; // Obtain and store the audio clips to play try { url1 = new URL ("file", "localhost", "westernBeat.wav"); url2 = new URL ("file", "localhost", "classical.wav"); url3 = new URL ("file", "localhost", "jeopardy.au"); url4 = new URL ("file", "localhost", "newAgeRythm.wav"); url5 = new URL ("file", "localhost", "eightiesJam.wav"); url6 = new URL ("file", "localhost", "hitchcock.wav"); } catch (Exception exception) {}
JukeBoxControls.java 3/6 music = new AudioClip[7]; music[0] = null; // Corresponds to "Make a Selection..." music[1] = JApplet.newAudioClip (url1); music[2] = JApplet.newAudioClip (url2); music[3] = JApplet.newAudioClip (url3); music[4] = JApplet.newAudioClip (url4); music[5] = JApplet.newAudioClip (url5); music[6] = JApplet.newAudioClip (url6); JLabel titleLabel = new JLabel ("Java Juke Box"); titleLabel.setAlignmentX (Component.CENTER_ALIGNMENT); // Create the list of strings for the combo box options String[] musicNames = {"Make A Selection...", "Western Beat", "Classical Melody", "Jeopardy Theme", "New Age Rythm", "Eighties Jam", "Alfred Hitchcock's Theme"}; musicCombo = new JComboBox (musicNames); musicCombo.setAlignmentX (Component.CENTER_ALIGNMENT);
JukeBoxControls.java 4/6 // Set up the buttons playButton = new JButton ("Play", new ImageIcon ("play.gif")); playButton.setBackground (Color.white); playButton.setMnemonic ('p'); stopButton = new JButton ("Stop", new ImageIcon ("stop.gif")); stopButton.setBackground (Color.white); stopButton.setMnemonic ('s'); JPanel buttons = new JPanel(); buttons.setLayout (new BoxLayout (buttons, BoxLayout.X_AXIS)); buttons.add (playButton); buttons.add (Box.createRigidArea (new Dimension(5,0))); buttons.add (stopButton); buttons.setBackground (Color.cyan);
JukeBoxControls.java 5/6 // Set up this panel setPreferredSize (new Dimension (300, 100)); setBackground (Color.cyan); setLayout (new BoxLayout (this, BoxLayout.Y_AXIS)); add (Box.createRigidArea (new Dimension(0,5))); add (titleLabel); add (Box.createRigidArea (new Dimension(0,5))); add (musicCombo); add (Box.createRigidArea (new Dimension(0,5))); add (buttons); add (Box.createRigidArea (new Dimension(0,5))); musicCombo.addActionListener (new ComboListener()); stopButton.addActionListener (new ButtonListener()); playButton.addActionListener (new ButtonListener()); current = null; }
JukeBoxControls.java 6/6 // Represents the action listener for the combo box. private class ComboListener implements ActionListener { public void actionPerformed (ActionEvent event) { if (current != null) current.stop(); current = music[musicCombo.getSelectedIndex()]; } } // Represents the action listener for both control buttons. private class ButtonListener implements ActionListener { public void actionPerformed (ActionEvent event) { if (current != null) current.stop(); if (event.getSource() == playButton && current != null) current.play(); } }
개요 예외 처리 try-catch 문 예외 전파 예외 클래스 입출력 예외 도구 팁과 단축 기호 콤보 박스 스크롤 페인과 분할 페인
스크롤 페인 (Scroll Pane) • 스크롤 페인은 수직/수평 스크롤 바를 제공하는 컨테이너이다. • 수직 및 수평 스크롤 바에 대해 사용 여부를 지정할 수 있는데, 따로 지정되지 않을 경우 필요에 따라 스크롤 바가 나타난다. • 예제: TransitMap.java