학습 목차
- 패키지
- 예외와 예외 처리
학습 개요
- 패키지는 Java 프로그램에서 사용할 수 있게 만들어진 클래스나 인터페이스의 라이브러리
- 예외 처리는 실행 중에 발생하는 경미한 오류를 처리하여 정상 상황으로 복구하기 위한 방법
- 패키지를 정의하고 사용하는 방법과 예외 처리 개념을 이행하고 활용할 수 있는 방법을 익힘
학습 목표
- 사용자 패키지 정의 가능
- 정의된 패키지를 사용하여 프로그램 작성 가능
- 예외의 종류 설명 가능
- 예외 처리 코드 작성 가능
1. 패키지
1-1. 패키지의 의미
- 관련이 있는 클래스와 인터페이스의 묶음
- 클래스와 인터페이스는 패키지 멤버로 존재
- 전체적으로 계층 구조의 클래스 라이브러리
- 패키지(폴더와 유사) 단위로 계층적으로 분류됨
- 패키지의 용도
- 쉽게 찾아 사용하기 위해 사용
- 이름 충돌을 피하기 위해 사용
graphics.Rectangle
와java.awt.Rectangle
는 구분됨
- 접근 제어를 위해 사용
1-2. 시스템 패키지
- JDK가 제공하는 클래스 라이브러리
- JDK와 함께 설치됨
- 클래스 파일들은 기능에 따라 패키지로 묶여 분류됨
- 일반적으로 jar 파일로 압축되어있음
C:\Program Files\Java\jdk-15.0.1\lib\jrt-fs.jar
C:\Program Files\Java\jdk-15.0.1\lib\src.zip
에서 소스 확인 가능
1-3. 제네릭 클래스
- 가장 기본이 되는 최상위 시스템 패키지는 java
- 대부분 시스템 패키지는
java.
으로 시작
- 대부분 시스템 패키지는
- Java 프로그램에서 상위 패키지와 하위 패키지의 구분을 위해 도트(
.
) 사용
ex)java.lang
,java.io
,java.awt
,java.awt.color
,java.util
등- Java 언어에서 가장 기본적 클래스는
java.lang
패키지에 존재 - 프로그램에서 클래스를 사용할 때는
java.io.IOException
과 같이 표현하는 것이 원칙
- Java 언어에서 가장 기본적 클래스는
1-4. 사용자 정의 패키지
- 패키지 정의 문법
1 2
package 패키지 이름; // 1개 이상의 클래스나 인터페이스 정의가 나옴
package
구문은 소스 코드 맨 앞에 위치해야함- 패키지 이름은 관례 상 모두 소문자로 작명
- 도트(
.
)로 구분하여 계층적으로 정의 가능 - 컴파일 하면 패키지가 만들어지고(또는 기존 패키지에) 클래스 파일(
.class
) 생성됨
- 패키지 정의
1 2 3 4 5
package com.vehicle; public class Car { String szType = "승용차"; }
- 컴파일 결과로
Car.class
생성 Car.class
는com.vehicle
패키지에 저장com.vehicle
의 위치- 컴파일 할 때
-d
옵션 사용하여 지정
ex) javac Car.java -d D:\javaClasses → D:\javaClass\com\vehicle\Car.class
- 컴파일 할 때
- 컴파일 결과로
1-5. Eclipse를 사용한 패키지 정의
- 메뉴 File → New → Package 선택
- 패키지에 해당하는 폴더 생성됨
- 생성된 패키지에서 클래스 생성
- 메뉴 File → New → Class 선택하여 클래스 이름과 함께 패키지 이름 입력
1-6. 패키지와 클래스의 사용
- 다른 패키지에 존재하는
public
클래스를 사용하려면 기본적으로 패키지 경로를 포함한 완전한 클래스 이름을 사용해야함- 프로그램에서 자주 사용한다면
import
구문 사용하는 게 좋음1 2
graphics.Rectangel myRect = new graphics.Rectangle(); java.util.Scanner s = new java.util.Scanner(System.in);
- 프로그램에서 자주 사용한다면
import
문- 1개 클래스 또는 패키지에 있는 클래스 전체를 import 할 수 있음
1 2
import 패키지 이름.클래스 이름; import 패키지 이름.*;
import
구문은 소스 코드 맨 앞에 위치- 단,
package
구문이 있다면 그 다음에 위치 - 프로그램에서 패키지 경로를 생략하고, 이름만 가지고 클래스나 인터페이스를 사용할 수 있게 함
- Java 프로그램에서
import java.lang.*;
구문은 자동 포함됨
- 1개 클래스 또는 패키지에 있는 클래스 전체를 import 할 수 있음
1-7. 패키지의 사용과 접근 제어
- 아래 프로그램에서
package
구문이 없다면 패키지 접근 수준의Car
클래스 사용 불가1 2 3 4 5 6 7 8 9 10 11 12
// package com.vehicle; import com.vehicle.*; class MyBus extends Bus { } // 기본 패키지에 MyBus 클래스 생성 public class PackageTest { public static void main(String args[]) { Bus bus = new Bus(); Car car = new Car(); // 오류 발생 } }
1 2 3
package com.vehicle; class Car {}
1 2 3
package com.vehicle; public class Bus extends Car {}
1-8. 클래스 찾기
- 컴파일하거나 실행할 때, 필요한 클래스(
A
)를 찾아야함- 컴파일러가
A.class
가 위치한 경로 또는A.class
를 포함하고 있는 jar 파일의 존재를 알아야함
- 컴파일러가
- JVM은 기본 패키지나 확장 패키지 외에 사용자 클래스도 찾을 수 있음
- 컴파일러는 환경 변수 CLASSPATH에 지정된 경로에서 사용자 클래스 찾을 수 있음
- 환경 변수 CLASSPATH
- CLASSPATH의 경로는 jar 파일 포함 가능
ex) 프로그램에서 graphics.Circle 클래스 사용 - CLASSPATH = 경로1;경로2;a.jar 라고 가정
- 이때, 경로1\graphics\Circle.class 또는 경로2\graphics\Circle.class 또는 a.jar에 \graphics\Circle.class가 있어야함
- CLASSPATH의 경로는 jar 파일 포함 가능
2. 예외와 예외 처리
2-1. 예외와 에러
- 에러(Error)
- 심각한 오류로 더 이상의 실행이 불가
- 예외(Exception)
- 경미한 오류로 복구 가능
- 예외는 정상적 실행 흐름을 방해하는 예외적 사건
- 예외 발생과 처리
- 메소드를 수행할 때 예외가 발생하면 예외 객체를 만들어 던짐
- 예외 처리 코드(exception handler)가 없으면, 오류 메시지가 출력되면서 프로그램이 즉시 종료됨
- 예외 처리 코드가 있으면, 예외 객체를 잡아 처리한 뒤, 프로그램은 계속 수행됨
- 예외 객체는
Exception
클래스(또는 하위 클래스)로 표현되며 예외 발생 정보를 가지고 있음
2-2. 예외 클래스의 계층 구조
- 예외 클래스의 계층 구조
- Unchecked Exception
- 예외 처리 코드 강제성 없음
- Checked Exception
- 반드시 예외 처리 코드 필요
- Unchecked Exception
2-3. 예외 처리(Exceotion handling)
- 예외가 발생했을 때 이 상황을 바로 잡아 계속 수행하도록 하는 것
- 예외 발생 시,
Exception
객체를 생성하고 throw함throw new MyException();
- throw 된 예외 객체를 예외 처리 코드가 catch하여 예외 처리
- 예외의 종류
- checked Exception이 발생할 수 있는 경우, 반드시 명시적인 예외 처리 필요
- 예외 처리 코드가 없을 경우 컴파일 오류 발생
- RuntimeException의 경우, 예외 처리 안해도됨
- 프로그램을 정확하게 작성하지 않은 경우 발생
ArithmeticException
,NullpointerException
,IndexOutOfBoundsException
- checked Exception이 발생할 수 있는 경우, 반드시 명시적인 예외 처리 필요
2-4. 예외 처리 방법
- 직접 처리
- 예외가 발생한 곳에서 예외 객체를 잡아서 처리
try-catch
구문 또는try-catch-finally
구문 사용하여 예외 처리- 일반 코드와 예외 처리가 분리되어 가독성 좋아짐
- 간접 처리(예외의 전파)
- 예외 발생 가능성이 있는 메소드의 선언에서 괄호 다음에
throws
예외 이름을 사용 - 그 메소드를 호출한 메소드에게 예외 처리를 전달 또는 위임하는 것
- 예외 발생 가능성이 있는 메소드의 선언에서 괄호 다음에
2-5. try-catch-finally 구문
- 문법
1 2 3 4
try { } catch(ExceotionType1 ex1) {} catch(ExceotionType2 ex2) {} finally {}
- 예외 객체를 throw하는 문장 또는 예외 발생 가능성이 있는 메소드의 호출 부분을
try
블록에 둠 catch
블록은 1개의 예외 유형 인자를 가지는 메소드와 유사- 처리해야 하는 예외 유형이 여럿이면
catch
블록도 여럿
- 처리해야 하는 예외 유형이 여럿이면
finally
블록은 생략 가능
- 예외 객체를 throw하는 문장 또는 예외 발생 가능성이 있는 메소드의 호출 부분을
2-6. try-catch-finally 구문의 실행
- 예외가 발생하면
try
블록은 즉시 종료 catch
블록이 여럿이면, 가장 적합한(발생된 예외 자료형과 일치하거나 상위 유형) 하나만 실행- 예외가 발생하지 않으면
catch
블록은 미실행 finally
블록은 예외 발생과 무관하게try
블록이 종료된 후 항상 실행됨- 할당 받아 사용했던 리소스를 원상 복구하기 위해
finally
블록을 주로 사용
ex)try
블록에서 open 했던 파일을 close하는 코드를finally
블록에 둠
- 할당 받아 사용했던 리소스를 원상 복구하기 위해
2-7. 예외의 직접 처리
- 예외의 직접 처리 방법
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
public class A { public void problem() throws RuntimeException { // problem 메소드에서 RuntimeException 예외 간접 처리 throw new RuntimeException(); // 예외 객체 생성, 예외 발생 } public void tryThis() { // tryThis 메소드 try { problem(); // 예외 발생되어 try문 즉시 종료 System.out.print("1"); } catch (RuntimeException x) { System.out.print("2"); } catch (Exception x) { System.out.print("3"); } finally { System.out.print("4"); } System.out.print("5"); } public static void main(String[] args){ A a = new A(); // A 클래스의 객체 생성 a.tryThis(); // a 클래스의 tryThis 메소드 호출 } } // 출력 결과 // 245
2-8. 예외의 간접 처리
- 예외를 발생시킬 수 있는 메소드를 호출하는 쪽에 예외 처리를 위임하는 것
- 예외의 전파
- 메소드 선언에서 발생시킬 수 있는 예외 유형을 표시
- 즉, 메소드 선언에서 괄호 다음에
throws
예외 유형을 사용1 2 3
pulic char getInput() throws IOException { nInput = System.in.read(); // 예외 발생 가능 }
- 메소드 선언에서
throws
절이 표시된 메소드를 호출하는 메소드는 예외 처리를 해야함1 2 3 4
try { c = obj.get } catch (IOException ex) { }
- 예외를 발생시킬 수 있는 메소드
ex)public FileInputStream(String name) throws FileNotFoundException
→FileInputStream
클래스의 생성자
ex)public int read() throws IOException
→InputStream
(또는Reader
) 클래스의 메소드 - 위와 같은 메소드를 호출할 때는 반드시 예외 처리 필요
- 위에서 발생 가능한 예외 유형은 checked Exception의 예시
2-9. 예외 처리 프로그램
- 예외 처리 프로그램 1
1 2 3 4 5 6 7 8 9 10 11 12 13
import java.io.*; public class ExceptionTest1 { public static void main(String args[]) { int b = 0; try { b = System.in.read(); // IOException을 발생 시킬 수 있는 메소드기 때문에 예외 처리 필요 } catch (IOException ex) { System.out.println(ex) } System.out.println((char)b); } }
- 예외 처리 프로그램 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
import java.io.*; class CharInput { int nInput = 0; public char getInput() throws IOException { // 예외 간접 처리로 예외 전파 nInput = System.in.read(); return (char)nInput; } } public class ExceptionTest4 { public static void main(String args[]) { CharInput charInput = new CharInput(); try { System.out.println(charInput.getInput()); // getInput 메소드 호출하여 예외 처리 필요 } catch (IOException ex) { System.out.println(ex); } } }
2-10. 사용자 정의 예외
- 사용자가 직접 예외 클래스를 작성 가능
- 일반적으로
Exception
클래스 상속 받음 throw
구문 사용해, 필요할 때 예외 객체 던질 수 있음1 2 3 4 5 6 7 8 9 10
class MyException extends Exception { public MyException() { super(); } public String toString() { return "MyException";} } class MyExceptionTest { public void testFunc(int x) throws MyException { if (x > 10) throw new MyException(); // 예외 객체 생성 -> 예외 발생 } }
학습 정리
- Java의 패키지는 관련이 있는 클래스와 인터페이스의 묶음이며 계층 구조로 구성
- 다른 패키지에 있는 클래스를 사용할 때는
import
구문을 사용하는 것이 편리 - Java 프로그램에서 필요한 클래스나 패키지는 환경변수 CLASSPATH에 포함되어 있는 경로상에서 찾을 수 있어야함
- Java 프로그램의 실행 도중 심각하지는 않지만 정상적 흐름을 벗어난 비정상적 상황이 발생할 수 있으며 예외라 부름
- checked Exception에 속하는 예외가 발생할 수 있는 경우, 반드시 예외 처리 구문 작성 필요
- 예외의 직접 처리를 위해
try-catch
구문을 사용하고, 예외를 전파하려면 메소드 선언에throws
예외유형 표시
연습 문제
Q1.
1
2
3
4
5
6
7
// Client 클래스를 myprogram.game 패키지에 위치시키려고 한다. Client 클래스를 정의하는 소스 파일의 맨 위에 포함시켜야 코드는 무엇인가?
// 1. package myprogram.game;
// 2. package myprogram.game.Client;
// 3. import myprogram.game;
// 4. import myprogram.game.Client;
// 1. package myprogram.game;
Q2.
1
2
3
4
5
6
7
8
9
10
11
public char getInput( ) /*_____*/ {
int nInput = System.in.read( );
return (char)nInput;
}
// 아래 밑줄 부분에 들어가야 할 내용은 무엇인가?
// 1. throw IOException
// 2. throws IOException
// 3. throw FileNotFoundException
// 4. throws FileNotFoundException
// 2. throws IOException
Q3.
1
2
3
4
// 프로그램 상에 클래스의 완전한 이름인 java.awt.Color로 표시하지 않고, 단순히 클래스 이름 Color만으로 표시하기 위해서 소스 파일의 맨 위에 작성해야 코드는 무엇인가?
import java.awt.*;
// import java.awt.Color; 또는 import java.awt.*;