본문 바로가기
Kosta DevOps 과정 280기/Java

예외 처리

by 롯슈83 2024. 5. 28.

예외

  • 프로그램 실행 중에 발생할 수 있는 예기치 않은 상황(예외)에 대한 처리를 말한다.
  • 예외에 대한 예를 들어보면 배열의 크기가 n이면 사용할 수 있는 인덱스는 0 ~ n-1 이다.  그 범위가 아닌 인덱스에 접근하는 상황을 뜻한다. 이 때는 ArrayIndexOutOfBoundsException 객체가 자동생성된다.
  • 또한 숫자 형식에 맞지 않으면 NumberFomatException객체가 생성된다.
  • 또 어떤 수를 0으로 나누는 상황에 문법 자체에 문법적 오류는 없으나, 실행 중에 사용자의 입력값이 바람직하지 않아 발생할 수 있는 예기치 않는 상황을 뜻한다.
  • 자바는 대부분 예기치 않은 상황에 대해서 클래스가 만들어져있다. 그래서 그 상황이 되면 예외 객체를 생성해준다.(오류에 대한 text)
  • 예외가 발생했을 때 자바는 new 예외클래스()를 한다.(예외 객체 생성)

예외처리 하는 방법

try{
//예외가 발생할 만한 문장들    
}catch(예외클래스명 변수명){
	//처리할 명령어(들)
}catch(예외클래스명 변수명){
	//처리할 명령어(들)
}finally{
	//반드시 처리할 명령어들(생략 가능)
}
//예외클래스명 변수명: Java에서 미리 만들어둔 객체 + 잡아올 변수명
//프로그램 실행 시에 두 개의 정수를 전달받아 나누기 한 결과를 출력

import java.util.Scanner;

class Calc02
{
	public static void main(String[] args)
	{
		try{
			int a = Integer.parseInt(args[0]);
			int b = Integer.parseInt(args[1]);
			int div = a/b;
			System.out.println("나누기 결과:"+div);
		}catch(ArrayIndexOutOfBoundsException e){
			System.out.println("나누기할 두 수를 전달해주세요!");
		}catch(NumberFormatException e){
			System.out.println("정수를 입력해주세요");
		}catch(ArithmeticException e){
			System.out.println("0으로 나눌 수 없습니다.");
		}
	}
}
  • 단, 실제 처리보다 예외처리떄문에 더욱더 길어지는 경향이 있었다.
  • 이 예외들의 조상이 있으므로 하나로 묶을 수 있다. 굳이 세분화하여 예외처리할 필요가 없다면 하나로 묶어서 처리를 하도록 한다. 단, Arithmetic Exception 만은 따로 두고 싶을경우 그것만 따로 빼서 예외처리를 한다.
  • 단, 포함 관계(상속 관계 등)에 있는 Exception을 쓸 경우, 자식을 먼저 쓰고 부모를 쓴다.
//프로그램 실행 시에 두 개의 정수를 전달받아 나누기 한 결과를 출력

import java.util.Scanner;

class Calc04
{
	public static void main(String[] args)
	{
		try{
			int a = Integer.parseInt(args[0]);
			int b = Integer.parseInt(args[1]);
			int div = a/b;
			System.out.println("나누기 결과:"+div);
		}catch(ArithmeticException e){
			System.out.println("0으로 나눌 수 없습니다.");
		}catch(Exception e){
			System.out.println("나누기할 두 정수를 확인해주세요");
		}
	}
}
  • 10번 줄의 catch(Exception e) 이 이미 모든 예외 상황을 처리 하기 때문에 12번 줄의 catch (ArithMethicException e)로 올 수 없어요.
  • 이와 같이 catch 절을 여러개 쓸 때에는 자식의 catch 절이 먼저 오도록 해야 한다.
  • 정상적으로 동작하는 경우는 try 안의 문장들이 다 동작이 되지만, 예외가 생기는 경우 catch문 안의 실행문들만 실행된다.
//프로그램 실행 시에 두 개의 정수를 전달받아 나누기 한 결과를 출력

import java.util.Scanner;

class Calc06
{
	public static void main(String[] args)
	{
		try{
			int a = Integer.parseInt(args[0]);
			int b = Integer.parseInt(args[1]);
			int div = a/b;
			System.out.println("나누기 결과:"+div);
			System.out.println("작업종료");
		}catch(ArithmeticException e){
			System.out.println("0으로 나눌 수 없습니다.");
		}catch(Exception e){
			System.out.println("나누기할 두 정수를 확인해주세요");
		}
	}
}
  • 단, finally 를 쓰면 작업 종료는 두 경우 모두 동작 하게 된다.
    • 정상동작하거나 예외가 발생하거나 반드시 동작시키고자 하는 명령어들을 써준다.
    • 예외 처리 하지 않은 동작도 여기서는 동작하게 된다. 만약 finally 뒤에 일반 문장에 둔다면 해당 문장은 동작하지 않는다.
    • return 문을 catch문에 적어주어도 동작한다.
//프로그램 실행 시에 두 개의 정수를 전달받아 나누기 한 결과를 출력

import java.util.Scanner;

class Calc08
{
	public static void main(String[] args)
	{
		try{
			int a = Integer.parseInt(args[0]);
			int b = Integer.parseInt(args[1]);
			int div = a/b;
			System.out.println("나누기 결과:"+div);
		}catch(ArithmeticException e){
			System.out.println("0으로 나눌 수 없습니다.");
		}finally{
			System.out.println("작업종료");
		}
	}
}

메소드 안에서 예외가 발생이 될 때

  • 메소드 자신이 직접 try ~catch를 써서 예외처리를 한다.
class ExceptionTest02 
{
	public static void calcDiv(int a, int b){
		try{
			int r = a / b;
			System.out.println("나누기 결과 :" + r);
		}catch(ArithmeticException e){
			System.out.println("0으로 나눌수 없음");
		}finally{
			System.out.println("작업종료");
		}
	}
	public static void main(String[] args) 
	{
    	try{
			calcDiv(4,2);
			calcDiv(4,0);
        }catch(ArithmeticException e){
        	System.out.println();
        }
	}
}
  • 메소드 호출하는 쪽으로 예외처리를 맞긴다. 
    • 메소드 선언부 매개변수 뒤쪽에 throws 를 적고 그 뒤에 예외들을 나열
    • 여기서 e 가 예외 메세지를 갖고 있기 때문에 읽어올 수 있다.
class ExceptionTest03
{
	public static void calcDiv (int a, int b) throws ArithmeticException{
		int r = a / b;
		System.out.println("나누기 결과 :" + r);
	}
	public static void main(String[] args) 
	{
		try{
			calcDiv(4,2);
			calcDiv(4,0);
		}catch(ArithmeticException e){
			System.out.println("예외발생 : "+e);
		}
	}
}
  • Exception()의 자식 클래스들은 super 로 내용을 전달받는다. 따라서 Excepttion에게 오류메세지를 가지고 있는것이다. 이때 Exception 의 부모 Throwble클래스를 보면 Error(오류), Exception(예외) 를 가지고 있다. 여기서 공통적으로 가지고 있는 printStackTrace() 메소드를 이용하면 어느 부분에서 에러가 났는지 확인할 수 있다.
    • printStackTrace(): 예외가 발생항면 어디에서 문제가 발생하였는지 추적해가면서 정보를 출력해줄 수 있다.(이 때 자신이 입력한 코드와 라이브러리에서 입력된 코드의 위치까지 나온다. 오류와 관련있는 코드들은 모두 나오는 형식이다.)
import java.io.FileWriter;
import java.io.IOException;

class FileWriterTest6
{
	public static void pro(String fname) throws IOException{
//		FileWriter fw = new FileWriter("c:/data/hello.txt");
		FileWriter fw = new FileWriter(fname);
		fw.write("hello java");
		fw.close();
		System.out.println("파일을 생성하였습니다.");
	}
	public static void main(String[] args) 
	{
		try{
			pro("c:/datja/hello.txt");
		}catch(IOException e){
			e.printStackTrace();
			//System.out.println("예외발생: "+e);
		}
	}
}

 

'Kosta DevOps 과정 280기 > Java' 카테고리의 다른 글

임계영역 (Critical Section)  (0) 2024.05.30
멀티스레드-2  (0) 2024.05.30
문자열 처리  (0) 2024.05.28
정규표현식  (0) 2024.05.27
문자열  (0) 2024.05.27