본문 바로가기

자바(java)

예외처리(Exception)

예외와 에러의 차이

 - 예외: 개발자가 대응할 수 있는 것.

 - 에러: 개발자가 대응할 수 없는 것.(단전, OS문제, JDK(JRE)의 문제)

 

 - 자바는 객체를 통해 예외를 처리한다.

 

 - 예외에서의 최상위 부모클래스: Exception

 

예외 발생 시 콘솔을 통해 알 수 있는 것.

1) 예외의 발생 위치  (java.lang.ArithmeticException: / by zero)

2) 예외의 발생 원인  (at kr.co.tj.Test.f2(Test.java:7))

public class Test {
	
	public void f2(int a, int b) {
		System.out.println(111);
		System.out.println(a/b);
		System.out.println(2222);
	}
}
=============================================
import kr.co.tj.Test;

public class MainEx {

	public static void main(String[] args) {
		Test t1 = new Test();
		t1.f2(10, 5);
		
		t1.f2(10, 0);  // 예외 발생
	}
}
================Console=========================
111
2
2222
111
Exception in thread "main" java.lang.ArithmeticException: / by zero  // 원인
	at kr.co.tj.Test.f2(Test.java:7)  // 위치
	at kr.co.main.MainEx.main(MainEx.java:16)  // 위치

 

예외처리:

 - try~catch와 throws를 구별해서 처리할 수 있어야 한다.

 - 예외가 아닌데 논리적으로 예외를 직접 유발하고 싶을 땐 throw를 이용한다.

 - 이 때, 사용자 정의 예외클래스를 생성해서 처리한다.

 - 끝으로, 예외 여부와 상관없이 무조건 실행해야 하는 코드는 finally구문으로 처리할 수 있다.

 

 - e.printStackTrace();  ->  예외발생 원인과 위치를 알려줌.

    - 개발할 때는 표기

    - 배포할 때는 미표기

 

try~catch

 - try에 예외가 발생할 가능성이 있는 코드를 적고,

    catch에 예외가 발생했을 때 실행할 코드를 적는다.

 - 예외가 발생할 가능성이 있는 코드 

    - 메서드에 매개변수가 있는 경우

 - catch에 들어갈 내용을 확실하게 알고 있고, 그에 대한 책임을 개발자가 감내할 수 있을 때 사용.

public class Test2 {
	
	public void w3(int idx) {
		
		int[] arr = {1};
		
		try {
			int num = arr[idx];
			
			System.out.println(num);
            
		} catch (Exception e) { // 원래는 ArrayIndexOutOfBoundsException
			System.out.println("죄송합니다.");
			System.out.println("100억원을 드리겠습니다.");
			e.printStackTrace();
		}
	}
}
===========================================================
import kr.co.tj.Test2;

public class MainEx {

	public static void main(String[] args) {

		Test2 t2 = new Test2();
        
		t2.w3(2);
	}
}
======================Console==============================
죄송합니다.
100억원을 드리겠습니다.
java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 1
	at kr.co.tj.Test2.w3(Test2.java:13)
	at kr.co.main.MainEx.main(MainEx.java:17)

 

 

Throws

 - 해당 메서드를 호출한 쪽에서 예외처리를 하도록 권한 위임.

 - 예외 발생의 원인을 정확히 모를 때 사용

public class Test4 {
	public void p2(String msg, int idx) throws Exception{ // StringIndexOutOfBoundsException
		System.out.println(1111);
		
		char c = msg.charAt(idx);  // 예외 발생 위치
		System.out.println(c);
		
		System.out.println(2222); //예외 발생 전까지 실행되고 예외 발생 뒤의 코드는 실행x
	}
}
============================================================
public class MainEx {

	public static void main(String[] args) {

		Test4 t4 = new Test4();
        
        try { //(throws 사용)
			t4.p2("hello", 1000);  // 예외 발생 위치
		} catch (Exception e) {
			System.out.println("죄송합니다.");
			System.out.println("늦더라도 제대로 고치겠습니다.");
		}
    }
}
=====================Console================================
1111
죄송합니다.
늦더라도 제대로 고치겠습니다.
java.lang.StringIndexOutOfBoundsException: String index out of range: 1000
	at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:48)
	at java.base/java.lang.String.charAt(String.java:1515)
	at kr.co.tj.Test4.p2(Test4.java:97)
	at kr.co.main.MainEx.main(MainEx.java:33)
public class Test4 {
	
	String[] weapons = {"활","검","대포"};
	String haveWeapon = weapons[0];
	
	public void changeWeapon(int idx) throws Exception{  // ArrayIndexOutOfBoundsException

		haveWeapon = weapons[idx];  // 예외 발생 위치
		System.out.println(haveWeapon+"으로 변경됨.");
	}
}
=====================================================
public class MainEx {

	public static void main(String[] args) {

		Test4 t4 = new Test4();
		
		try {
			t4.changeWeapon(3);  // 예외 발생 위치
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			System.out.println("무기 변경 실패");
			System.out.println("바른 값을 넣으세요.");
		}
    }
}
===================Console==========================
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
	at kr.co.tj.Test4.changeWeapon(Test4.java:18)
	at kr.co.main.MainEx.main(MainEx.java:13)
무기 변경 실패
바른 값을 넣으세요.

 

 

finally

 - 작업이 실패하든 성공하든 무조건 실행해야 하는 코드는 finally구문으로 처리

 - try~catch와 같이 사용

 - 주의사항: try~catch 구문 밖에 작성하는 것과 구별해야 함(같은 묶음은 finally로 처리)

 - return보다 효력이 강력함.

    - try와 catch에 return문이 있어도, 반드시 finally구문을 실행하고 return문이 나중에 실행됨.

 -  나중에 I/O 학습과 DB학습 때 사용

public class Test7 {
	
	public int me2(int idx) {
		int[] arr = {1, 2};
		
		try {
			System.out.println(arr[idx]);  // 예외 발생 위치
			
			return 200;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("빠른 시일 내에 조치하겠음.");
			
			return 500;
		} finally { // return보다 강함
			System.out.println("close()메서드 호출");
		}
	}
}
=============================================================
public class MainEx {

	public static void main(String[] args) {
		Test7 t7 = new Test7();
		t7.me2(10);  // 예외 발생 위치
	}
}
=======================Console===============================
java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 2
	at kr.co.tj.Test7.me2(Test7.java:9)
	at kr.co.main.MainEx.main(MainEx.java:10)
빠른 시일 내에 조치하겠음.
close()메서드 호출

 

 

Throw

 - 문법적으로 예외가 아닌 상황이지만 논리적으로 예외일 때, 강제로 예외를 유발하는 기능

    ex) 정책적인 것들(댓글의 욕 제한)

 - 메서드 뒤에 throws Exception 삽입(문법적으로 예외가 아니므로 Exception만 가능)

public class Test8 {
	
	public void ee1(String reply) throws Exception {  //throws Exception 삽입
		String[] arr = {"fuck", "ㅅㅂ"};
		
		for(int i=0; i<arr.length; i++) {
			String msg = arr[i];
			
			if(reply.contains(msg)) {
				throw new Exception("욕하지 마");  // return대신 throw
			}
		}
		System.out.println(reply);
	}
}
============================================================================
import kr.co.tj.Test8;

public class MainEx {

	public static void main(String[] args) {
		
		Test8 t8 = new Test8();
		
		try {
			t8.ee1("센스 있는데");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("불온문자가 포함되어 있음");
		}
		
		try {
			t8.ee1("ㅅㅂ");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("불온문자가 포함되어 있음");
			
		}
    }
}
=========================Console===================================
센스 있는데
java.lang.Exception: 욕하지 마
	at kr.co.tj.Test8.ee1(Test8.java:12)
	at kr.co.main.MainEx.main(MainEx.java:21)
불온문자가 포함되어 있음

 

 

사용자 정의 예외클래스

 - throw를 사용하면 문법적 예외가 아니므로 관련 예외 객체를 어떤 클래스로 만들지에 대한 문제점이 생긴다.

    - 당연히 이와 관련된 예외 클래스는 존재하지 않는다.

 - 따라서 직접 논리적 예외와 관련된 예외클래스를 만들어주고, 이를 사용한다.

 - throw클래스의 구조 + 사용자 정의 예외클래스

 - 사용자 정의 예외클래스 생성방법

    - 클래스명 extends Exception

    - Add default serial version ID(마우스 올려놓기)

    - 슈퍼클래스의 사용자 생성자 생성(String에 대해서만)

    - throw구문 사용 위치에서 Exception을 직접 만든 예외클래스로 바꾸기

public class DoNotSwearException extends Exception { //직접 만든 Exception + extends Exception

	private static final long serialVersionUID = 1L;

	// 슈퍼클래스(Exception)의 사용자 생성자->String만
	public DoNotSwearException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}
	
}
================================================================
public class Test8 {
	
	public void ee1(String reply) throws Exception {
		String[] arr = {"인마"};
		
		for(int i=0; i<arr.length; i++) {
			String msg = arr[i];
			
			if(reply.contains(msg)) {
             	// 우리가 직접 만든 Exception으로 바꾸기
				throw new DoNotSwearException("욕하지 마세요."); 
			}
		}
		System.out.println(reply);
	}
}
==================================================================
public class MainEx {

	public static void main(String[] args) {
		Test8 t8 = new Test8();
		
		try {
			t8.ee1("야, 인마!");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("불온문자가 포함되어 있음.");
		}
	}
}
=============================Console===============================
kr.co.tj.DoNotSwearException: 욕하지 마세요.
	at kr.co.tj.Test8.ee1(Test8.java:12)
	at kr.co.main.MainEx.main(MainEx.java:11)
불온문자가 포함되어 있음.

 

 

 

 

'자바(java)' 카테고리의 다른 글

Calendar(GetInstance)  (0) 2023.03.14
Random  (0) 2023.03.14
내부클래스(Inner Class)  (0) 2023.03.13
Enum(Enumeration)  (0) 2023.03.10
람다식(Lambda)  (0) 2023.03.10