본문 바로가기
프로그래밍 언어/Java 프로그래밍

Java Day9 - 패키지와 예외처리, 쓰레드

by Hyeon_ 2021. 11. 11.

패키지와 예외처리

패키지

  • 자바의 클래스들을 모아 놓은 폴더
    • 폴더의 경로를 표현할 때 사용하는 구분자
      • 윈도우즈: \, 맥, 리눅스: /
    • 자바에서는 패키지의 경로를 표현할 때 . 을 사용
  • 패키지 주의 사항
    • 모든 클래스는 반드시 하나의 패키지에 포함
    • 하나의 소스파일(.java)에는 첫 번째 문장으로 단 한 번의 패키지 선언 가능
  • 패키지란?
    • 동일한 특징을 갖는 열개의 클래스를 하나의 폴더로 관리하는 방법

 

birds-Birds, gound-Ground, Main의 파일을 생성한 것

  • Brids.java
package StartJava.animal.birds;

public class Birds {
    public static void main(String[] args) {

    }
}
  • Ground.java
package StartJava.animal.ground;

public class Ground {
    public static void main(String[] args) {

    }
}
  • Main,java (Birds와 Ground에 있는 함수들을 불러와서 사용 가능)
// '*'(와일드카드), all 이라는 의미로 사용
// 동일한 패키지라면 모두 import 해서 사용 가능

import StartJava.animal.birds.Birds;
import StartJava.animal.ground.*;

// 라이브러리(개발에 필요한 유용한 클래스를 미리 만들어서 제공
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Birds bird = new Birds();
        Ground ground = new Ground();
    }
}

예외처리

  • 코드를 작성하면서 발생하는 예외(Error, Warning, ...)에 대한 처리 방법 2가지
    1. 고전적인 예외처리(LBYL)
      • Look Befroe You Leap (도약하기 전에 확인 해라)
      • 코드를 실행하기 전에 예외가 발생하지 않도록 미리 검증하고 실행을 하자
      • 즉, 발생할 수 있는 모든 예외적인 상황에 대해 대비하라
      • 현실적으로는 불가능한 방법
        • 완벽하게 예외를 제외할 수 없음
        • 안전한 소프트웨어는 불가능 하다는 것이 학계 정설!!
    2. EAFP
      • It's Easier Ask Forgiveness Than Permission
      • 허락보다 용서가 쉽다
      • 일단, 실행하고 예외가 발생하면 그때 처리하자
      • 실제로 고전적인 방법보다 예외 관리가 더 쉬워지는 경우가 있음
  • 예제 - 1
package Standard_Java;
// 418p. 예제 8-2

public class ExceptionTest {
    public static void main(String[] args) {
        int number = 100;
        int result = 0;

        for(int i = 0; i< 10; i++){
            // 어떤 수이든 0으로 나눌 수 없음
            result = number / (int)(Math.random() * 10);
            System.out.println(result);
        }
    }
}
Exception in thread "main" java.lang.ArithmeticException: / by zero
    at Standard_Java.ExceptionTest.main(ExceptionTest.java:10)
  • 예제1 오류 해결(고전적인 방식)
// 418p. 예제 8-2

public class ExceptionTest01 {
    public static void main(String[] args) {
        int number = 100;
        int result = 0;

        for(int i = 0; i< 10; i++){
            int div = (int)(Math.random() * 10);
            if(div!=0){
                result = number / div;
            }
            System.out.println(result);
        }
    }
}

예외의 종류

  • 에러는 예외의 한 종류
  • 예외에도 여러가지가 있음(에러, 경고 등)
  • 에러는 여러가지 예외 중에서도 프로그램 실행에 영향을 줄만큼 심각한 오류
  • 에러의 종류도 여러가지
    • 컴파일 에러
      • 컴파일 할 때 발생하는 에러(javac)
      • *.java -> *.class
      • 대부분이 문법적인 오류가 있는 경우
      • 처기 쉬움
    • 런타임 에러
      • 문법 오류는 체크가 끝(실행에 문제가 없는 상태)
      • 실행했을 떄 문제가 나오는 경우
      • 재현되지 않는 에러는 해결이 불가능 한 경우가 많음

예외의 기본 구조

try{
    ...
}
catch(예외1) {
    ...
}
catch(예외2){
    ...
}
  • 예외가 발생할 것 같은 코드를 try 구문으로 감싸준다
    • Java는 try 블록에 있는 명령어에 대해 모니터링 수행
  • 예외가 발생한다면?
    • catch 블록으로 예외를 넘기게 됨
    • catch 블록에서 해당 예외 처리
  • 예제1 오류 해결(try-catch를 활용한 예외처리)
    • try-catch문을 추가해서 ArithmeticException이 발새할 경우 0을 화면에 출력하도록 함
package Standard_Java;
// 418p. 예제 8-2

public class ExceptionTest01 {
    public static void main(String[] args) {
        int number = 100;
        int result = 0;

        for(int i = 0; i< 10; i++){
            try{
                result = number / (int)(Math.random() * 10);
                System.out.println(result);
            }
            catch (ArithmeticException e){
                System.out.println("0");
            }
        }
    }
}
  • 예제1 오류 해결(try - catch - finally 구문)
package Standard_Java;
// 418p. 예제 8-2

public class ExceptionTest01 {
    public static void main(String[] args) {
        int number = 100;
        int result = 0;

        for(int i = 0; i< 10; i++){
            try{
                result = number / (int)(Math.random() * 10);
            }
            catch (ArithmeticException e){
                System.out.println("산술 예외");
            }
            catch(Exception e){
                System.out.println("그 외 다른 예외들");
            }
            finally {
                System.out.println("최종적으로 무조건 실행되는 블록");
            }
            System.out.println(result);
        }
    }
}

예외의 흐름

  • 예외가 발생하는 곳과, 처리되는 곳이 다르다.
  • 이를 예외가 흘러간다고 표현
  • 예외를 반드시 처리해야 함
package Standard_Java;
// 418p. 예제 8-2

class Others extends Object {
    // 예외의 흐름
    public int convToint(String strs){
        return Integer.parseInt(strs); // 예외 발생
    }
}

public class ExceptionTest01 {
    public static void main(String[] args) {
        Others exam = new Others();
        int num = 0;
        try {
            num = exam.convToint("a");
        }
        catch (Exception e){
            System.out.println("예외 발생"); // 예외가 처리되는 곳
        }
        System.out.println(num);

    }
}
  • 예외 클래스를 직접 만들어서 처리하기
package Standard_Java;
// 418p. 예제 8-2

// 모든 예외는 Exception 클래스를 상속 받아서 정의
// 직접 예외를 정의
class UserException extends Exception{
    UserException() {
        System.out.println("내가 만든 예외");
    }
}

// 예외의 흐름
class Sub {
    public int convToInt(String strs) {
        try {
            return Integer.parseInt(strs);
        }
        catch (Exception e){
            System.out.println("예외가 발생한 곳에서 처리");
            // 예외도 객체
            throw new ArithmeticException(); // 예외 던져줌
        }
    }
}

class Others extends Object {
    public int middleMethod(String strs) throws UserException{
        Sub s = new Sub();
        try {
            return s.convToInt(strs);
        } catch (ArithmeticException e) { // 던진 예외 받는 곳
            System.out.println("middleMethod 에서 예외가 처리됨");
            throw new UserException();
        }
    }
}

public class ExceptionTest01 {
    public static void main(String[] args) {
        Others exam = new Others();
        int num = 0;
        try {
            num = exam.middleMethod("a");
        }
        catch (Exception e){
            System.out.println("결국 여기까지 오고야 말았구나"); // 예외가 처리되는 곳
        }
        System.out.println(num);

    }
}

Thread(스레드)

Process(프로세스)

  • Windows에서 실행중인 프로세스 확인 방법
    • Ctrl + Shift + Esc
  • 운영체제에서 작업을 실행하는 단위 = Process
    • 포그라운드 프로세스 (눈에 보이는 실행. )
    • 백그라운드 프로세스 (눈에 보이지 않는 실행)

Thread(스레드)

  • 프로세스의 작업 단위
  • 프로세스는 자신이 해야 되는 작업을 여러 개의 스레드로 작게 쪼갤 수 있음
  • 이렇게 나눠진 여러개의 스레드를 동시에 실행하는 것이 (병렬)
// 자바에서의 스레드는 Thread 클래스를 상속받아서
// run 메서드를 구현하도록 되어 있음
// 객체에서 start()를 호출하면 자동으로 run()이 실행되도록 구성

public class Thread01 extends Thread{
    @Override
    public void run() {
        System.out.println("thread 실행");
    }

    public static void main(String[] args) {
        Thread01 example = new Thread01();
        example.start();
    }
}
  • Thread는 순차 지원이 되지 않는다.
    • 다음의 코드를 실행해보면 스레드의 값이 순서대로 나오지 않는다는 것을 확인할 수 있다.
    • 전체 스레드가 종료되기 전에 main 메서드가 종료되는 것도 발생 가능하다.
// 자바에서의 스레드는 Thread 클래스를 상속받아서
// run 메서드를 구현하도록 되어 있음
// 객체에서 start()를 호출하면 자동으로 run()이 실행되도록 구성

public class Thread01 extends Thread{
    int num;
    Thread01(int num){
        this.num = num;
    }

    @Override
    public void run() {
        System.out.printf("%d번 thread 실행\n", this.num);
    }

    public static void main(String[] args) {
        for(int i = 0; i <= 10; i++){
            Thread01 example = new Thread01(i);
            example.start();
        }
        System.out.println("Main end");
    }
}
0번 thread 실행
10번 thread 실행
Main end
9번 thread 실행
8번 thread 실행
7번 thread 실행
6번 thread 실행
5번 thread 실행
3번 thread 실행
1번 thread 실행
4번 thread 실행
2번 thread 실행