AngelPlayer`s Diary

예외 처리 (Exception)

구문 에러, 논리 에러 등으로 인해서 오류와 예외가 발생할 수 있음

 

오류 : 시스템 레벨에서 프로그램에 심각한 문제를 야기하여 프로그램을 종료

예외 : 실행 중인 프로그램을 비정상적으로 종료시키지만, 예외 상황을 미리 예측하여 처리 가능함 -> 예외 처리

 

 

try/catch/finally

자바 예외처리는 try/catch/finally 구문을 통해서 이루어짐

try {
    실행할 코드
} catch (e1) {
    e1 예외가 발생할 경우 실행할 코드
} catch (e2) {
    e2 예외가 발생할 경우 실행할 코드
} finally {
    예외 발생 여부와 상관없이 무조건 실행할 코드
}

 

 

try-catch 구문을 중첩하여 사용 시, 안쪽의 try문(line 2)에서 예외가 발생할 때 안쪽 catch 문(e1, e2)에서 예외처리가 되지 않는 경우, 바깥쪽 catch문(e3, e4)까지 확인함  

try {
    try {
        실행할 코드
    } catch (e1) {
        e1 예외가 발생할 경우 실행할 코드
    } catch (e2) {
        e2 예외가 발생할 경우 실행할 코드
    } 
} catch (e3) {
    e3 예외가 발생할 경우 실행할 코드
} catch (e4) {
    e4 예외가 발생할 경우 실행할 코드
} finally {
    예외 여부와 상관없이 실행할 코드
}

 

 

Exception 클래스

예외의 조상 클래스

 

예외처리에도 순서가 있음 (Exception > IOException)

IOException 보다 Exception가 먼저 오면 IOException은 절대로 실행되지 못함

 

|를 사용하여 예외처리를 동시에 처리 가능함

try { } catch (IOException | SQLException e) { }

 

 

Throwable 클래스

Exception 클래스와 Error 클래스의 부모 클래스

예외처리를 던지는데 사용함

 

- 예외가 발생한 메소드에서 처리

public class Exception {
    static void handlingException() {
        try {
            throw new Exception(); // 예외 발생을 위한 코드
        } catch (Exception e) {
            System.out.println("호출된 메소드에서 예외가 처리됨!"); // 실행
        }
    }

    public static void main(String[] args) {
        try {
            handlingException();
        } catch (Exception e) {
            System.out.println("main() 메소드에서 예외가 처리됨!");
        }
    }
}

 

- 예외 발생 시 호출한 메소드로 예외를 던지는 처리

던지는 행위를 하는 메소드는 "throws 예외_종류"를 명시해야 함

예외 발생 메소드, 예외 처리 메소드를 제외한 예외가 거쳐가는 메소드는 "extends Exception"을 명시해야 함

public class Exception {
    static void handlingException() throws Exception { // 예외 종류 명시
        throw new Exception(); // 예외 발생
    }

     public static void main(String[] args) {
        try {
            handlingException();
        } catch (Exception e) {
            System.out.println("main() 메소드에서 예외가 처리됨!"); // 실행
        }
    }
}

 

 

 

스레드

프로세스 : 실행 중인 프로그램

스레드 : 프로세스 내에서 작업을 수행하는 주체

프로세스 내부에는 한 개 이상의 스레드가 존재

 

 

스레드 생성 방법

Runnable 인터페이스를 구현
Thread 클래스를 상속

class ThreadWithClass extends Thread {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(getName()); // 현재 실행 중인 스레드의 이름을 반환함.
            try {
                Thread.sleep(1000); // 1초간 스레드를 멈춤.
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class ThreadWithRunnable implements Runnable {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()); // 현재 실행 중인 스레드의 이름을 반환함.
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class Prog {
    public static void main(String[] args){
        ThreadWithClass thread0 = new ThreadWithClass(); // Thread 클래스를 상속받는 방법
        Thread thread1 = new Thread(new ThreadWithRunnable()); // Runnable 인터페이스를 구현하는 방법

        thread0.start(); // 스레드의 실행
        thread1.start(); // 스레드의 실행
    }
}

 

- 람다식을 통한 스레드 표현

new Thread(new Runnable() {
    public void run() {
        System.out.println("전통적인 방식의 일회용 스레드 생성");
    }
}).start();
 
new Thread(()->{
    System.out.println("람다 표현식을 사용한 일회용 스레드 생성");
}).start();

 

 

 

스트림 API

저장된 데이터에 접근하는 정형화된 방법

배열, 컬렉션, 파일 등에 저장된 데이터를 같은 방법으로 다루게 하는 기능

 

 

특징

외부 반복을 통해 작업하는 컬렉션과는 달리 내부 반복을 통해 작업을 수행
재사용이 가능한 컬렉션과는 달리 단 한 번만 사용 가능
원본 데이터를 변경하지 않음
필터-맵(filter-map) 기반의 API를 사용하여 지연(lazy) 연산을 통해 성능을 최적화
parallelStream() 메소드를 통한 손쉬운 병렬 처리를 지원

 

 

스트림 API 동작 흐름

스트림 생성

2. 스트림 변환

3. 스트림 사용

 

 

스트림 API 생성 가능 목록

컬렉션
배열
가변 매개변수
지정된 범위의 연속된 정수
특정 타입의 난수들
람다 표현식
파일
빈 스트림

- 컬렉션에서 스트림 사용

import java.util.*;
import java.util.stream.*;

public class prog {
	public static void main(String[] args){
		ArrayList<Integer> list = new ArrayList<Integer>();
		
		list.add(4);
		list.add(2);
		list.add(3);
		list.add(1);
		
		// 컬렉션에서 스트림 생성
		Stream<Integer> stream = list.stream();
		// forEach() 메소드를 이용한 스트림 요소의 순차 접근
		stream.forEach(System.out::println);		
	}
}

forEach는 스트림 요소를 하나씩 소모해가며 순차적으로 접근하기 때문에 같은 스트림으로는 메소드를 한 번만 호출 가능함 -> stream이라는 변수는 더 이상 쓸 수 없음

 

 

- 일부 데이터를 통한 스트림 생성

import java.util.*;
import java.util.stream.*;

public class prog {
	public static void main(String[] args){
		String[] arr = new String[]{"넷", "둘", "셋", "하나"};
		
		// 배열에서 스트림 생성
		Stream<String> stream1 = Arrays.stream(arr);
		stream1.forEach(e -> System.out.print(e + " "));
		System.out.println();
		
		// 배열의 특정 부분만을 이용한 스트림 생성
		Stream<String> stream2 = Arrays.stream(arr, 1, 3);
		stream2.forEach(e -> System.out.print(e + " "));
	}
}

 

 

 

 

공유하기

facebook twitter kakaoTalk kakaostory naver band