본문 바로가기

BackEnd/Java

[java] ch11 예외 처리 1

728x90

1. 예외와 예외 클래스

   ▷ 예외 : 잘못된 사용 또는 코딩으로 인한 오류

   ▷ 에러와 달리 예외 처리를 통해 계속 실행 상태를 유지할 수 있습니다.

   ▷ 일반 예외(Exception) : 컴파일러가 예외 처리 코드 여부를 검사하는 예외

   ▷ 실행 예외(Runtime Exception) : 컴파일러가 예외 처리 코드 여부를 검사하지 않는 예외

 

 

2. 예외 처리 코드

   ▷ 예외 발생 시 프로그램의 갑작스러운 종료를 막고 정상 실행을 유지할 수 있게 처리하는 코드

   ▷ 예외 처리 코드는 try-catch-finally 블록으로 구성

   ▷ trycatch-finally 블록은 생성자 내부와 메소드 내부에서 작성

 

◎ 예외 발생 예시 1

public class Example1 {
	
	public static void printLength(String data) {
		int result = data.length();
		System.out.println("문자 수 : " + result);
	}

	public static void main(String[] args) {
		System.out.println("[프로그램 시작]\n");
		printLength("ThisIsJava");
		printLength(null);
		System.out.println("[프로그램 종료]");	
	}
}


//	출력 :
//	[프로그램 시작]
//	
//	문자 수 : 10
//	Exception in thread "main" java.lang.NullPointerException
//		at java0118.Example1.printLength(Example1.java:6)
//		at java0118.Example1.main(Example1.java:13)

 

◎ 예외 발생 예시 2

package java0118;

public class Example2 {
	
	public static void printLength(String data) {
		try {
			int result = data.length();
			System.out.println("문자 수 : " + result);			
		} catch(NullPointerException e) {
			System.out.println(e.getMessage());  // ①
//			System.out.println(e.toString());    // ②
//			e.printStackTrace();                 // ③
		} finally {
			System.out.println("[마무리 실행]\n");
		}
	}

	public static void main(String[] args) {
		System.out.println("[프로그램 시작]\n");
		printLength("ThisIsJava");
		printLength(null);
		System.out.println("[프로그램 종료]");	
	}
}


//	출력 :
//	[프로그램 시작]
//	
//	문자 수 : 10
//	[마무리 실행]
//	
//	null      -------------------------------------------------- ① 출력
//	java.lang.NullPointerException   --------------------------- ②, ③ 출력
//		at java0118.Example2.printLength(Example2.java:7)   ---- ③ 출력
//		at java0118.Example2.main(Example2.java:21)         ---- ③ 출력
//	[마무리 실행]
//	
//	[프로그램 종료]


▷ catch부분에  System.out.println("null 값은 입력하시면 안됩니다."); 라는 문구를 넣어서 null 값이 나타나면
'null 값은 입력하시면 안됩니다.'라는 문구가 출력되도록 만들어줄 수 있습니다.

NullPointerException이란 null 값이 발생이 되면 catch 블록을 실행하는 것입니다.

▷ getMessage : null (간단한 결과 출력)
▷ toString : 조금 더 상세 설명
▷ printStackTrace() : 오류가 발생한 위치까지 알려줍니다.

try를 통해 우선 실행하고 예외가 발생하면 catch를 통해서 잡고 그렇지 않으면 finally로 바로 넘어갑니다.

 

◎ 예외 발생 예시 3

public class Example3 {
	public static void main(String[] args) {
		try {
			Class.forName("java.lang.String");
			System.out.println("java.lang.String 클래스가 존재합니다.");
		} catch(ClassNotFoundException e){
			e.printStackTrace();
		}
		
		System.out.println();
		
		try {
			Class.forName("java.lang.String2");
			System.out.println("java.lang.String2 클래스가 존재합니다.");
		} catch(ClassNotFoundException e){
			e.printStackTrace();
		}
	}
}

//	출력 :
//	java.lang.String 클래스가 존재합니다.
//	
//	java.lang.ClassNotFoundException: java.lang.String2
//		at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
//		at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
//		at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
//		at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
//		at java.lang.Class.forName0(Native Method)
//		at java.lang.Class.forName(Class.java:264)
//		at java0118.Example3.main(Example3.java:15)


 Class.forName("패키지 ... 클래스") : ClassPath 위치에서 주어진 클래스를 찾는 코드입니다.
   ▶ 이미 있는 것만 찾아줄 수 있습니다.

만약 찾지 못하면 ClassNotFoundException이라는 일반 예외가 발생합니다.

 

 

3. 다중 catch로 예외 처리하기

   ▷ catch 블록의 예외 클래스는 try 블록에서 발생된 예외의 종류를 말합니다. 해당 타입의 예외가 발생하면 catch 블록이 선택되어 실행합니다.

   ▷ catch 블록이 여러개라도 catch 블록은 단 하나만 실행됩니다.

   ▷ 처리해야 할 예외 클래스들이 상속 관계에 있을 때는 하위 클래스 catch 블록을 먼저 작성하고 상위 클래스 catch 블록을 나중에 작성해야합니다.

 

◎ 다중 catch 사용 예시 1 (array)

public class Example4 {
	public static void main(String[] args) {
		String[] array = {"100", "1oo"};
		
		for(int i=0; i<=array.length; i++) {
			try {
				int value = Integer.parseInt(array[i]);
				System.out.println("array[" + i + "]: " + value);
			} catch(ArrayIndexOutOfBoundsException e) {
				System.out.println("배열 인덱스가 초과됨 : " + e.getMessage());
			} catch(NumberFormatException e) {
			System.out.println("숫자로 변환할 수 없음 : " + e.getMessage());
			}
		}
	}
}

//	출력 : 
//	array[0]: 100
//	숫자로 변환할 수 없음 : For input string: "1oo"
//	배열 인덱스가 초과됨 : 2


▷ ArrayIndexOutOfBoundsException : 배열의 크기(인덱스)를 초과하면 실행되도록 합니다.
 NumberFormatException : 숫자타입이 아닐 때 발생하는 예외입니다.

 

◎ 다중 catch 사용 예시 2 (array)

public class Example5 {
	public static void main(String[] args) {
		String[] array = {"100", "1oo"};
		
		for(int i=0; i<=array.length; i++) {
			try {
				int value = Integer.parseInt(array[i]);
				System.out.println("array[" + i + "]: " + value);
			} catch(ArrayIndexOutOfBoundsException e) {
				System.out.println("배열 인덱스가 초과됨 : " + e.getMessage());
			} catch(Exception e) {
				System.out.println("실행에 문제가 있습니다.");
			}
		}
	}
}

//	출력 : 
//	array[0]: 100
//	실행에 문제가 있습니다.
//	배열 인덱스가 초과됨 : 2


▷ Exception을 사용하면 나머지 모든 예외 관련해서 동일한 출력을 나타날 수 있게 합니다.

 

◎ 다중 catch 사용 예시 3 (array)

public class Example6 {
	public static void main(String[] args) {
		String[] array = {"100", "1oo", null, "200"};
		
		for(int i=0; i<=array.length; i++) {
			try {
				int value = Integer.parseInt(array[i]);
				System.out.println("array[" + i + "]: " + value);
			} catch(ArrayIndexOutOfBoundsException e) {
				System.out.println("배열 인덱스가 초과됨 : " + e.getMessage());
			} catch(NullPointerException | NumberFormatException e) {
				System.out.println("데이터에 문제가 있음 : " + e.getMessage());
			}
		}
	}
}

//	출력 : 
//	array[0]: 100
//	데이터에 문제가 있음 : For input string: "1oo"
//	데이터에 문제가 있음 : null
//	array[3]: 200
//	배열 인덱스가 초과됨 : 4


▷ catch에서 '|' 는 논리 연산자가 아닌 연결 연산자입니다. 하지만 역할은 or로 동일합니다.
그리고 예외 발생시 try, catch를 사용하면 중간에 종료되는 것이 아니라 모든 결과를 출력합니다.
   ▶ 따라서, array[1], array[2]에서 에러가 발생했지만 array[3]까지 출력이 되는 것을 볼 수있습니다.

 

예외처리는 예외가 발생해도 오류만 나타나지 않고 결과를 끝까지 출력할 수 있도록 만들어줍니다.

 

어디에서 틀렸는지 알 수 있으니 아주 유용하겠죠??

 

다음 장에서 한 번 더 다뤄볼게요!

 

많은 분들의 피드백은 언제나 환영합니다! 많은 댓글 부탁드려요~~

 

728x90