KH 15일차 (Exception,Thread)
14일차인 오늘은 Exception(예외 처리), Thread 에 대해서 학습했다.
(1) Exception
: 대부분의 프로그램에서는 에러가 발생한다. 그렇기 때문에 프로그램에는 다양한 에러의 대처할 수 있는 기능을 구현해야 한다.
만약 에러에 대처하는 기능이 없다면 프로그램이 비정상적으로 동작하거나 종료하게 된다. 이를 해결하고 프로그램을 정상적으로 실행하는데 방해가 되는 에러들을 Exception(예외)라고 한다.
.RuntimeException : 실행시간에 발생한 예외 처리
.IOException : 입출력에 관련된 예외 처리
.NoSuchMethodException : 메소드를 찾을 수 없을 때 예외처리
.InterruptedException : 인터럽트에 관련된 예외 처리
.ClassNotFoundExcetpion : 클래스를 찾을 수 없을 때 예외처리
package ja_0720;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Exception_1 {
public static void main(String[] args) throws IOException{
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
while(true) {
try {
System.out.println("첫번째 값을 입력하세요");
int num1 = Integer.parseInt(input.readLine());
System.out.println("두번째 값을 입력하세요");
int num2 = Integer.parseInt(input.readLine());
System.out.println(" " + num1 + " / " + num2 + " = " + (num1/num2));
}catch (NumberFormatException e) {
System.err.println("숫자를 입력하세요.");
System.err.println(e.getMessage());
//e.printStackTrace();
}catch (ArithmeticException e) {
System.err.println("몫이 0이 될 수 없습니다.");
System.err.println(e.getMessage());
// Exception 은 범위가 가장 넓은 예외처리이기 때문에 가장 아래로 내려가야함.
}catch (Exception e) {
System.err.println("Exception 이 발생하였습니다.");
}
finally {
System.out.println("\n 항상 실행되는 내용 \n");
}
}
}
}
BufferedReader은 scanner와 System.out.println()보다 속도 측면에서 훨씬 빠르기 때문에
(입력된 데이터가 바로 전달되지 않고 버퍼를 거쳐 전달되므로 데이터 처리 효율성을 높임)
많은 양의 데이터를 처리할 때 유리하다.
while(true) 속의 try - catch문으로 발생할 수 있는 모든 예외를 처리해주고 있는 모습.
finally속의 내용은 예외처리와 상관없이 항상 실행된다.
여기서 중요한것은 제일 범위가 넓은 Exception을 catch 가장 마지막에 적어줘야된다는 것이다. Exception보다 범위가
좁은 예외처리를 아래에서 해준다면, 오류가 발생한다.
public class Exception_2 {
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.err.println(e.getMessage());
}
System.out.print(result + "\t");
}
}
}
10번의 반복 속에 Math.random()을 활용해서 무작위로 0값이 나와서 result값에 예외가 발생할 때
ArithmeticException로 예외처리를 해주는 모습.
package ja_0720;
import java.io.FileNotFoundException;
public class Exception_4 {
public static void main(String[] args) {
try {
System.out.println("===============예외 발생전==============");
throw new FileNotFoundException("IO => 입출력 예외 발생~");
} catch (NumberFormatException e) {
System.out.println("내가 만든 예외 222!!!!");
e.printStackTrace();
System.out.println(e.getMessage());
} catch (ArithmeticException e) {
System.out.println("내가 만든 예외 3333!!!!!");
e.printStackTrace();
System.out.println(e.getMessage());
} catch (Exception e) {
System.out.println("내가 만든 예외 4444!!!!!");
e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
throw new를 이용해서 일부러 예외를 발생하고 있는 모습 발생시킨 예외에 따라서 catch구문에 걸리게 되고
각각의 예외 상황에 맞게 getMessage()가 출력되고 있는 모습이다.
package ja_0720;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Exception_6 {
//JVM에게 떠넘기기.
// ArithmeticException, IOException, NumberFormatException => Exception
//static 로드 되는 순간 만들어져 있는 것.
public static void main(String[] args){
try {
input();
} catch (ArithmeticException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// input();
}
public static void input() throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while(true) {
System.out.println("첫번째값을입력하세요 =>");
//integer.parseInt String을 int로 변환시켜줌.
int num1 = Integer.parseInt(in.readLine());
System.out.println("두번째값을입력하세요 =>");
int num2 = Integer.parseInt(in.readLine());
dividing(num1, num2);
}
}
public static void dividing(int num1, int num2){
System.out.println(num1 + " / " + num2 + " = " + num1 / num2);
}
}
static으로 선언되어 있는 input() 메서드가 2개의 값을 받아서 int형으로 변환시켜 저장하고 dividing()메서드를 호출하는 모습
static으로 선언되어 있는 dividing() 메서드가 호출되어, 매개변수인 num1과 num2 를 알맞게 출력해주고 각각의 예외를 main클래스에서 JVM으로 넘겨주어 예외처리가 된다.
(2) Thread
: Java는 스레드를 사용하기 위해 두가지 방법을 제공합니다.
첫번째는 java.lang.Thread 클래스를 상속받아 스레드를 생성하는 방법이고
두번째는 java.lang.Runnable 인터페이스를 implements 해서 스레드를 생성하는 방법이다.
package ja_0720;
class MyThread extends Thread{
public void run() {
try {
for(int i = 0;i < 20; i++) {
//Thread를 상속받고 있기 때문에 Thread 생략가능.
Thread.sleep(1000); // 1초를 멈추게 함
System.out.println(" " + i + " * " + i + " = " + (i*i));
}
}catch (InterruptedException e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
public class ThreadTest_1 {
public static void main(String[] args) {
MyThread thread = new MyThread();
//thread.start() // 쓰래드 호출
thread.run(); // 메소드 호출
}
}
package ja_0720;
class MyThread_2 extends Thread{
@Override
public void run() {
try {
for(int i = 0;i < 20; i++) {
Thread.sleep(1000);
System.out.println(" " + i +" 번 쓰래드 ^^^^^^^^");
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadTest_2 {
public static void main(String[] args) {
MyThread_2 thread_1 = new MyThread_2();
thread_1.start();
// 쓰래드 (strat)로 돌려보면 뒤죽박죽(스레드가) 나오지만
// 메서드 (run)으로 돌려보면 아주정갈하게(메서드가) 출력된다.
try {
for(int i = 0;i < 20; i++) {
Thread.sleep(1000);
System.out.println(" " + i +" main쓰레드 ^^^^^^^^");
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}