[java] 예외처리

진아·2025년 4월 2일

자바

목록 보기
7/7
post-thumbnail

< 예외의 이해 >

< Systax Erorr >

문법에러로 컴파일이 불가능하여 실행되지 않는 상태 / 빨간색으로 강조


< Runtime Erorr >

문법적으론 아무런 문제가 없지만 프로그램 실행 -> 논리적 오류로 인해 에러


< 고전적 예외처리 >

프로그램이 에러가 발생할 확률이 높다면 조건문등을 활용


< 예외처리 >

자바에서는 예외 처리를 대처하기 위한 try ~ catch ~ finally 문법 제공


< 예외처리 예제 >


< 예외의 이해 >

public class Ex01_예외의_이해 {
	public static void main(String[] args) {
    	/** 1) Syntax Error (문법에러) */
    	// java의 코딩 규칙을 지키지 않아 컴파일이 불가능한 상태
    	// 대체로 편집기에서 빨간색으로 강조 표시된다.
    	// 수정하지 않으면 컴파일 자체가 불가능
    	// 대입연산자가 누락되어 문법에러
    	// int a 100;

    	/** Runtime error (실행중 발생하는 에러)*/
    	// 문법적으로는 아무런 문제가 없지만
    	// 프로그램이 실행하면서 겪는 논리적 오류로 인해 발생하는 에러
    	// 컴파일이 되어 실행되는 과정에서 프로그램이 다운된다.
    	int[] k = {10,20,30};

    	for(int i = 0; i< 5; i++){
        	// 인덱스가 3인 데이터가 없으므로 i가 3일 때 에러
        	System.out.println(k[i]);
    	}


    	// 에러가 발생하는 순간 프로그램이 다운되므로 아래 구문은 실행 되지 못한다
    	System.out.println("fin : ");
	}

}

< 고전적 에외처리 >

/**				

*
프로그램이 실행되는 과정에서 에러가 발생할 가능성이 있다면
조건문등을 사용하여 그 상황을 피해가도록 구성해야 한다.
*
*
*/

public class Ex02_고전적_예외처리 {
	public static void main(String[] args) {
    	int[] k = {10,20,30};

    // 반복문의 조건을 수정할 수 없는 상황이라고 가정할 경우
    	for (int i = 0; i<5; i++){
        	// 반복문안에서 i가 배열의 길이를 초과하지 않을 경우에만 출력하도록 
        	// 조건문을 구성해야한다.
        	if (i <3){
            	System.out.println(k[i]);
        	}

    	}
    	System.out.println("fin : ");
	}
}

< 예외처리 >

 /**

프로그래머가 대응할수 없는 경우의 발생하는 에러 예시

*
1) 파일복사를 수행하는 기능에서 하드디스크이 용량이 가득찬 경우
2) 다운로드를 수행하는 기능에서 인터넷 접속이 끊긴경우
3) USB 파일을 저장하는 과정에서 USB 연결이 강제로 해제된 경우

*
위와 같은 상황은 if문으로 해결이 어렵기 때문에
자바에서는 예외 상황에 대처하기 위한 Try ~ Catch ~ finally 문법을 제공함
*/

public class Ex03_예외처리 {
	public static void main(String[] args) {
    	int[] k = {10,20,30};

		try {

        	for (int i = 0; i <5; i++) {
            System.out.println(k[i]);
        }


    	} catch (Exception e) {
        	/** try 블록 안에서 에러가 발생할 경우 실행되는 블록 */
        	// try 와 catch는 꼭 명시되어야 함
        	// try 블록을 수행하는 과정에서 에러가 발생하면 프로그램이 다운되지 않고 
        	// 그 즉시 catch 블록으로 제어가 이동한다


        	System.out.println("에러가 발생했습니다");
        	System.out.println("에러의 원인: " + e.getMessage());

        	System.out.println("====================");
        	e.printStackTrace();
        	System.out.println("====================");
    		} 	finally {
        		/** 에러의 발생여부에 상관없이 무조건 실행되는 블록 */
        		// 필요하지 않다면 생략가능
        		System.out.println(" 배열의 탐색 종료");
    		}
    	System.out.println("fin :)");
		}
	}

<에러상황에 세분화>

public class Ex04_에러상황의_세분화 {
	public static void main(String[] args) {
    	int [] data = {100, 20, 300};


    	try {
        	// 여기서발생할 수 있는 에러상황
        	// 1) 배열의 index를 초과한 경우
        	// 2) 0으로 나눈 경우 i=0 일때

        	for (int i =2; i >= -1; i--){
            	int k = data[i];
            	System.out.println(k);
        	}

    } catch (ArrayIndexOutOfBoundsException e1) {
        // catch 블록을 발생할 수 있는 에러에 경우에 수에 따라 여러개를 정의 하면
        // 상항별로 에러를 구분하여 대응할 수 있다.
        System.out.println("배열의 인덱스를 초과했습니다.");

    } catch (ArithmeticException e2) {
        System.out.println("잘못된 연산 입니다.");
    } catch (Exception e){
        System.out.println("알수없는 에러가 발생했습니다.");
    	}
	}
}

< Calc >

public class Calc {
	private static Calc current;

	public static Calc getInstance() { // 싱글톤 객체
    	if (current == null) {
        	current = new Calc();
    	}

    	return current;
	}


	private Calc() {
    	super();
	}




	// 런타임 에러가 발생할 경우 메서드 안에 직접 try ~ catch 사용
	public int divied (int x, int y){
    	int z =0;

    	try {
        	z = x / y;

    	} catch (Exception e) {
        	System.out.println("[divied 에러] 0으로 나눌수 없습니다. ");
    	}

    	return z;
	} 

	// throws 구문 사용

	public int diviedEx (int x , int y){
    	return x / y;
	}
}

< 예외처리2 >

import java.util.Scanner;

public class Ex05_예외처리 {

	public static void main(String[] args) {
    	Scanner reader = new Scanner(System.in);

    System.out.print("x를 입력하세요 ");
    int x = reader.nextInt();

    System.out.print("y를 입력하세요 ");
    int y = reader.nextInt();

    reader.close();

    Calc c = Calc.getInstance();


    int z = c.divied(x, y);

    System.out.printf("[divied] %d 나누기 %d는 %d 입니다.\n",x,y,z);
    System.out.println("----------------------");

    // throws가 적용된 메서드를 호출할때는 Try ~ catch가 강제된다.

    int a =0;
    try {
        a = c.divied(x, y);

    } catch (Exception e) {
        System.out.println("[divied] 0으로 나눌수 없습니다.");
    }

    System.out.printf("[diviedEx] %d 나누기 %d는 %d 입니다\n", x,y,a);
    
    // java에는 개발자가 예측하기 어려운 예외상황이 발생할 가능성이 있는 기능들에 대해
    // 이미 모두 throws가 적용된 형태로 제공된다.
    // 그러므로 개발자는 컴파일러가 강제하는 try ~ catch문을 사용함으로
    // 예외상황에 자연스럽게 대비할 수 있게 된다.
	}
}



/**

java에서 제공하는 에러 클래스를 상속받은 클래스
개발자가 직접 정의한 비정상적인 상황을 의미하는 클래스
*/

public class MyKorException extends Exception {
	public MyKorException() {
    	super("국어점수가 벗어났습니다.");
	}

	public MyKorException (String message) {
    	super(message);
	}
}


/**

java에서 제공하는 에러 클래스를 상속받은 클래스
- 개발자가 직접 정의한 비정상적인 상황을 의미하는 클래스
*/

public class MyMathException extends Exception {
	public MyMathException() {
    	super("수학 범위를 벗어났습니다.");
	}

	public MyMathException(String message) {
    	super(message);
	}
}



public class Student {
	private String name;
	private int kor;
	private int math;


public String getName() {
    return this.name;
}

public void setName(String name) {
    this.name = name;
}

public int getKor() {
    return this.kor;
}

public void setKor(int kor) throws MyKorException {
    if (kor < 0 || kor > 100) {
        // 이 라인에서 에러를 강제로 발생시킴
        // --> throw 명령은 try ~ catch 구문으로 감싸지거나
        //     throw 명령을 사용하는 메서드는 throws를 통해
        //     강제로 발생하는 에러에 대한 처리를 호출하는 위치로 떠넘겨야 한다.

        throw new MyKorException();
    }
    
    this.kor = kor;
}

public int getMath() {
    return this.math;
}

public void setMath(int math) throws MyMathException {
    if(math <0 ){
        throw new MyMathException("수학점수가 0보다 작습니다.");

    }

    if (math < 100) {
        System.out.println("수학점수가 100보다 큽니다.");

    }
    this.math = math;
}


@Override
public String toString() {
    return "{" +
        " name='" + getName() + "'" +
        ", kor='" + getKor() + "'" +
        ", math='" + getMath() + "'" +
        "}";
}


}



public class Ex06_사용자_정의_예외 {
	public static void main(String[] args) {
    	Student s = new Student();

    	s.setName("헬로월드");
    



    
    try {
        s.setKor(-123);
    } catch (MyKorException e) {
        System.err.println("[MyKorException] >>" + e.getMessage()); // 에러메세지 출력
    }
    





    try {
        s.setKor(123);
    } catch (MyKorException e) {
       System.err.println("[MyKorException] >>" + e.getMessage());
    }





    try {
        s.setMath(-1);
    } catch (MyMathException e) {
        System.err.println("[MyMathException] >>"  + e.getMessage());
    }



    try {
        s.setMath(101);
    } catch (MyMathException e) {
        System.err.println("[MyMathException] >>"  + e.getMessage());
    }

    System.out.println(s.toString());
	}
}
profile
진아의 코딩기록⭐

0개의 댓글