Java 기본(3) - 예외처리 / 쓰레드

김정욱·2021년 6월 12일
0

Java

목록 보기
3/13
post-thumbnail

ref : 남궁성님의 유튜브 강의를 참조했습니다
https://www.youtube.com/watch?v=fcRapZYB29c&list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&index=97

기타

  • 메소드매개변수객체를 넘기면 Call By Reference로 동작
  • 모든 객체Object상속
  • 객체생성자가 하나도 없으면 자동으로 기본 생성자(Default Constructor) 생성
    (사용자가 하나라도 만들면 기본 생성자를 만들어주지 X)
  • instanceof 키워드를 통해 인스턴스의 타입을 확인할 수 있다
  • 인터페이스다중 상속이 가능
  • 접근 지정자
    • private : 해당 클래스에서만 접근 가능
    • default : 해당 패키지 내에서만 접근 가능
    • protected : 동일 패키지 내의 클래스 혹은 상속받은 외부 패키지의 클래스에서 사용 가능
    • public : 모든 클래스와 패키지에서 사용 가능

예외 ?

프로그램 오류


에러와 예외

  • 런타임 에러(runtime error)는 크게 에러(error) / 예외(exception) 로 구분
    • 에러(error) : 심각한 오류 / 프로그램 코드에 의해 수습 불가능
    • 예외(exception) : 미약한 오류 / 프로그램 코드에 의해 수습 가능

예외 클래스의 계층 구조

  • 프로그램 코드로 수습이 가능런타임 에러Exception이 우리가 처리할 대상
  • Exception 계층은 아래처럼 세분화 해서 2가지로 구분할 수 있다

예외 처리

예외(Exception)

  • 예외(Exception) ?
    • error의 일종으로, 발생시 시스템 및 프로그램을 불능상태를 야기함
    • 종류
      • 일반 예외(Exception) : 컴파일 시점에 발생하는 예외
      • 실행 예외(RuntimeException) : 프로그램 실행시 발생하는 예외

예외 처리

  • 예외 처리 ?
    • 프로그램에서 예외발생시키고, 처리하는 과정
  • 예외 처리 구문 : try ~ catch ~ finally
    • try : 수행할 문장
    • catch : 처리할 예외
    • finally : 처리할 예외에 상관 없이 반드시 수행되는 부분
  • 예외 발생 키워드
    • throw : 메소드 내에서 상위 블럭으로 예외를 던지는 것
    • throws : 메소드에서 상위 메소드예외를 던지는 것
  • 예외 처리 방법
    • try-catch문 --> 직접 처리
      • throw예외를 발생시킨 후 적절한 처리 수행
    • 예외 선언 --> 예외 떠넘기기
      • throws를 통해 발생시 호출한 메서드로 예외를 넘기기 위한 선언
      • throw예외를 발생시키면 throws에 따라 호출한 메서드예외를 떠넘기게 됨
    • 은폐 --> try-catch는 쓰되, 처리를 하지 않는 것
  • 사용자 정의 예외 만들기
    • 조상Exception / RuntimeException 중에서 선택해서 상속(extends)
      : 가능하면 RuntimeException으로 만들어서 선택적으로 예외 처리할 것
    • String 매개변수를 갖는 생성자를 만들어 부모 생성자 호출
      : 예외 메시지를 통해 부모(Exception / RuntimeException) 생성자 호출 - super 사용

예외 발생시

  • 예외가 발생하면 해당 예외에 맞는 예외 객체생성
    • 예외 객체에는 예외에 대한 정보들이 존재
    • 다양한 API를 통해서 접근하고 사용할 수 있음
  • catch 블럭순회하며 해당 예외 처리수행
    • e.printStackTrace()
      : 예외발생 당시의 호출스택에 있던 메서드의 정보예외 메시지 출력
    • e.getMessage()
      : 발생한 예외클래스인스턴스에 저장된 메시지 얻기

실행 예외(RuntimeException) 처리

(FoolException.java)

public class FoolException extends RuntimeException {
}

(main.java)

public class Test {
    public void sayNick(String nick) {
        if("fool".equals(nick)) {
        /* 특정 조건을 만족할 경우 throw를 통해 예외를 발생 시킴 */
            throw new FoolException();
        }
        System.out.println("당신의 별명은 "+nick+" 입니다.");
    }

    public static void main(String[] args) {
        Test test = new Test();
        test.sayNick("fool");
        test.sayNick("genious");
    }
}

(결과)

Exception in thread "main" FoolException
    at Test.sayNick(Test.java:7)
    at Test.main(Test.java:15)

일반 예외(Exception) 처리

(FoolException.java)

public class FoolException extends Exception {
}

(main.java)

public class Test {
    public void sayNick(String nick) {
        try {
            if("fool".equals(nick)) {
                /* throw로 예외 발생 시킴 */
                throw new FoolException();
            }
            System.out.println("당신의 별명은 "+nick+" 입니다.");
        }catch(FoolException e) {
            /* Exception은 컴파일 시 발생하므로 바로 처리해주는 코드가 있어야 정상 실행! */
            System.err.println("FoolException이 발생했습니다.");
        }
    }

    public static void main(String[] args) {
        Test test = new Test();
        test.sayNick("fool");
        test.sayNick("genious");
    }
}

throws로 예외 던지기

  • 특정 메소드 내부에서 예외를 발생시켜 처리하기 위해서는 throw만 사용하면 됨
  • 하나의 트랜잭션 수행에서 발생한 예외상위 메소드로 던져서 전체 작업을 처리하려면 throws가 필요
  • 메소드의 끝 부분throws 키워드예외를 작성
/* 상품발송이라는 하나의 트랜잭션 */
상품발송() {
    try {
        포장();
        영수증발행();
        발송();
    }catch(예외) {
       모두취소();
    }
}

포장() throws 예외 {
   ...
}

영수증발행() throws 예외 {
   ...
}

발송() throws 예외 {
   ...
}

checked 예외 / unchecked 예외

  • checked 예외
    • 컴파일러예외 처리 여부를 체크(예외 처리 필수)
    • try ~ catch 필수
    • Exception과 자손들
  • unchecked 예외
    • 컴파일러예외 처리 여부를 체크 안함(예외 처리 선택)
    • try ~ catch 선택
    • RuntimeException과 자손들

쓰레드(Thread)

  • Thread.start() 를 통해서 쓰레드를 실행
    (Thread순서에 상관 없이 동시에 실행되기 때문에 순서가 정해지지 X)
  • Thread.join() 을 통해서 실행 순서 제어 가능

(Test.java)

/* Thread를 상속받고 실행하는 run 메소드를 구현해줘야 한다 */
public class Test extends Thread {
    int seq;
    public Test(int seq) {
        this.seq = seq;
    }
    public void run() {
        System.out.println(this.seq+" thread start.");
        try {
            Thread.sleep(1000);
        }catch(Exception e) {
        }
        System.out.println(this.seq+" thread end.");
    }
}

(Main.java)

public static void main(String[] args) {
    ArrayList<Thread> threads = new ArrayList<Thread>();
    for(int i=0; i<10; i++) {
        Thread t = new Test(i);
        /* thread 실행 */
        t.start();
        threads.add(t);
    }

    for(int i=0; i<threads.size(); i++) {
        Thread t = threads.get(i);
        try {
        /* thread.join()을 통해 실행이 끝날 때 까지 기다린 후 다음 수행! */
            t.join();
        }catch(Exception e) {
        }
    }
    System.out.println("main end.");
}

Runnable

  • 쓰레드 객체를 생성 하는 방법
    • Thread 직접 상속
    • Runnable 인터페이스 상속
  • Runnable 인터페이스를 통해 쓰레드 객체를 생성하면 상속 및 기타 등등에서 좀더 유연해짐!
import java.util.ArrayList;

public class Test implements Runnable {
    int seq;
    public Test(int seq) {
        this.seq = seq;
    }
    public void run() {
        System.out.println(this.seq+" thread start.");
        try {
            Thread.sleep(1000);
        }catch(Exception e) {
        }
        System.out.println(this.seq+" thread end.");
    }

    public static void main(String[] args) {
        ArrayList<Thread> threads = new ArrayList<Thread>();
        for(int i=0; i<10; i++) {
            Thread t = new Thread(new Test(i));
            t.start();
            threads.add(t);
        }

        for(int i=0; i<threads.size(); i++) {
            Thread t = threads.get(i);
            try {
                t.join();
            }catch(Exception e) {
            }
        }
        System.out.println("main end.");
    }
}
profile
Developer & PhotoGrapher

0개의 댓글