Home [Java 프로그래밍] 7강 - 패키지와 예외 처리
Post
Cancel

[Java 프로그래밍] 7강 - 패키지와 예외 처리

💡해당 게시글은 방송통신대학교 김희천 교수님의 'Java 프로그래밍' 강의를 개인 공부 목적으로 메모하였습니다.



학습 목차


  1. 패키지
  2. 예외와 예외 처리

학습 개요


  • 패키지는 Java 프로그램에서 사용할 수 있게 만들어진 클래스나 인터페이스의 라이브러리
  • 예외 처리는 실행 중에 발생하는 경미한 오류를 처리하여 정상 상황으로 복구하기 위한 방법
  • 패키지를 정의하고 사용하는 방법과 예외 처리 개념을 이행하고 활용할 수 있는 방법을 익힘

학습 목표


  1. 사용자 패키지 정의 가능
  2. 정의된 패키지를 사용하여 프로그램 작성 가능
  3. 예외의 종류 설명 가능
  4. 예외 처리 코드 작성 가능



1. 패키지


1-1. 패키지의 의미

  • 관련이 있는 클래스와 인터페이스의 묶음
    • 클래스와 인터페이스는 패키지 멤버로 존재
  • 전체적으로 계층 구조의 클래스 라이브러리
    • 패키지(폴더와 유사) 단위로 계층적으로 분류됨
  • 패키지의 용도
    • 쉽게 찾아 사용하기 위해 사용
    • 이름 충돌을 피하기 위해 사용
      • graphics.Rectanglejava.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과 같이 표현하는 것이 원칙

1-4. 사용자 정의 패키지

  • 패키지 정의 문법
    1
    2
    
      package 패키지 이름;
      // 1 이상의 클래스나 인터페이스 정의가 나옴
    
    • package 구문은 소스 코드 맨 앞에 위치해야함
    • 패키지 이름은 관례 상 모두 소문자로 작명
    • 도트(.)로 구분하여 계층적으로 정의 가능
    • 컴파일 하면 패키지가 만들어지고(또는 기존 패키지에) 클래스 파일(.class) 생성됨
  • 패키지 정의
    1
    2
    3
    4
    5
    
      package com.vehicle;
    
      public class Car {
          String szType = "승용차";
      }
    
    • 컴파일 결과로 Car.class 생성
    • Car.classcom.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 선택하여 클래스 이름과 함께 패키지 이름 입력 image

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-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가 있어야함



2. 예외와 예외 처리


2-1. 예외와 에러

  • 에러(Error)
    • 심각한 오류로 더 이상의 실행이 불가
  • 예외(Exception)
    • 경미한 오류로 복구 가능
    • 예외는 정상적 실행 흐름을 방해하는 예외적 사건
  • 예외 발생과 처리
    • 메소드를 수행할 때 예외가 발생하면 예외 객체를 만들어 던짐
    • 예외 처리 코드(exception handler)가 없으면, 오류 메시지가 출력되면서 프로그램이 즉시 종료됨
    • 예외 처리 코드가 있으면, 예외 객체를 잡아 처리한 뒤, 프로그램은 계속 수행됨
    • 예외 객체는 Exception 클래스(또는 하위 클래스)로 표현되며 예외 발생 정보를 가지고 있음

2-2. 예외 클래스의 계층 구조

  • 예외 클래스의 계층 구조
    image
    • Unchecked Exception
      • 예외 처리 코드 강제성 없음
    • Checked Exception
      • 반드시 예외 처리 코드 필요

2-3. 예외 처리(Exceotion handling)

  • 예외가 발생했을 때 이 상황을 바로 잡아 계속 수행하도록 하는 것
  • 예외 발생 시, Exception 객체를 생성하고 throw함
    • throw new MyException();
  • throw 된 예외 객체를 예외 처리 코드가 catch하여 예외 처리
  • 예외의 종류
    • checked Exception이 발생할 수 있는 경우, 반드시 명시적인 예외 처리 필요
      • 예외 처리 코드가 없을 경우 컴파일 오류 발생
    • RuntimeException의 경우, 예외 처리 안해도됨
      • 프로그램을 정확하게 작성하지 않은 경우 발생
      • ArithmeticException, NullpointerException, IndexOutOfBoundsException

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 블록은 생략 가능

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 FileNotFoundExceptionFileInputStream 클래스의 생성자
    ex) public int read() throws IOExceptionInputStream(또는 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.*;

[Java 프로그래밍] 6강 - 제네릭과 람다식

[Java 프로그래밍] 8강 - java.lang 패키지