예외처리 throws

jinkyung·2021년 1월 14일
0

JAVA

목록 보기
21/29

throws

: 호출한 쪽으로 던진다. catch가 받는다.

package com.bit.day09.am;

public class Ex14 {

	public static void main(String[] args) {
		try{
		func("1234a");
		}catch(NumberFormatException e){}
	}

	
	public static void func(String msg) throws NumberFormatException{
//		try{                             원래대로라면 여기에 try catch
		System.out.println(Integer.parseInt(msg));
//		} catch(NumberFormatException e){}
		
	}
}

아래의 경우는 반드시 해야할 것을 안하면 나는 에러. 컴파일이 안된다. 예외처리를 해주어야 한다.

(Cloneable 인터페이스를 상속해야함)

메소드의 선언부에 예외를 선언 --> 이 메소드를 사용하기 위해서 어떤 예외들이 처리돼야하는지 쉽게 알 수 있다.

package com.bit.day09.am;

public class Ex14 {
	public static void main(String[] args) {

			func(new Ex14());

	}

	public static void func(Ex14 me) {		
			Object obj=me.clone();		//CloneNotSupportedException가 뜬다.
	}
}

**clone()**은 Cloneable 인터페이스를 상속해야 쓸 수 잇는 Object 클래스의 메소드이다.
package com.bit.day09.am;

public class Ex14 {
	public static void main(String[] args) {
		try{
			func(new Ex14());
		} catch(CloneNotSupportedException e){
			System.out.println("에러회피");		//interface상속을 안해서 클론을 못하는 클래스
		}
	}
	
	public static void func(Ex14 me) throws CloneNotSupportedException{		
			Object obj=me.clone();
	}
}
//throws가 에러를 해결해주는 것이 아니고, 에러가 발생했을시에 이렇게 해라~ 라고 명령을 주는 것이기 때문에 
//throws Exception을 해도 "에러회피"가 출력되는 것이다.
package com.bit.day09.am;

public class Ex14 implements Cloneable{         //클론인터페이스 상속
	public static void main(String[] args) {  
		try{
			func(new Ex14());
		} catch(CloneNotSupportedException e){
			System.out.println("에러회피");		
		}
	}
	
	public static void func(Ex14 me) throws CloneNotSupportedException{		
			Object obj=me.clone();
	}
}

**RuntimeException** :하다보니 나는 에러. 실행해야 아는 에러. 실행 전까진 전혀 문제없는 에러.

그러므로 예외처리를 강제하지 않는다. (ex)NumberFormatException


에러 발생시키기

: 이러한 예외처리를 해야할 것이다 라고 보여줄 수 있다.

package com.bit.day09.am;

public class Ex15 {

	public static void main(String[] args) {
		try{
			func(2,0);                //실수에서 0은 무한이므로 연산이 안된다.
		} catch(Exception e){         //여기서 exc를 받아서 처리함.
			System.out.println("예외처리");
		}
	}

	public static void func(int a,int b) throws Exception {

		if(Double.isInfinite(1.0*a/b)){			
			Exception exc=new Exception();	//최상위 클래스로 객체생성했기 때문에 에러가 떠도 설명이 안뜬다고?
			throw exc;
		}
		System.out.println(1.0*a/b);         //infinity가 출력된다.
	}
}
package com.bit.day09.am;

class MyExc extends Exception{	
	MyExc(String msg){            //string을 받는 생성자
		super(msg);		//Exception class의 string을 받는 생성자 호출	
	}
}


public class Ex15 {

	public static void main(String[] args) {
		try{
			func(2,0);
		} catch(MyExc e){
			e.printStackTrace();             //에러 메세지 출력메소드
		}
	}

	public static void func(int a,int b) throws MyExc {

		if(Double.isInfinite(1.0*a/b)){			
			MyExc exc=new MyExc("0으로 나눠서 에러");		
			throw exc;
		}
		System.out.println(1.0*a/b);
	}
}

package com.bit.day09.am;

class MyExc extends Exception{	
	public MyExc(){
		super("0으로 나눠서 에러");	    //string받는 생성자를 다른방식으로 호출 
	}

}

public class Ex15 {

	public static void main(String[] args) {
		try{
			func(2,0);
		} catch(MyExc e){
			e.printStackTrace();     //에러메시지 '0으로 나눠서 에러'가 뜬다
		}
	}

	public static void func(int a,int b) throws MyExc {

		if(Double.isInfinite(1.0*a/b)){			
			MyExc exc=new MyExc();		
			throw exc;
		}
		System.out.println(1.0*a/b);
	}
}

**printStackTrace() **: 콘솔에다 출력하는 것이 아니라 스택에 있는 것을 출력하는 것. 저 명령을 받는 순간 에러메세지를 스택에 담아놓고, 시스템에 여유가 생기는 시점에 출력해준다(남는 자원을 이용해 수행). 돌아가는 시스템에 큰 영향을 주지않고 볼 수 있는 방법이다. (에러메세지는 프로그램 돌아가는데 있어서는 중요도가 떨어지기 때문에 이 방법을 사용하는 것이 좋다)

반면 sysout은 그 시점에 반드시 출력해야하기 때문에 이 작업을 수행하기 전엔 다른것으로 못넘어간다.

package com.bit.day09.am;

class MyExc extends Exception{	
	public MyExc(){
		super("0으로 나눠서 에러");			
	}
	
}



public class Ex15 {

	public static void main(String[] args) {
		try{
			func(2,0);
		} catch(MyExc e){
			e.printStackTrace();   
			System.out.println(e.getMessage());
			System.out.println(e.toString());
			System.out.println(e.getStackTrace()[0]);
			System.out.println(e.getStackTrace()[1]);
		}
	}

	public static void func(int a,int b) throws MyExc {

		if(Double.isInfinite(1.0*a/b)){			
			MyExc exc=new MyExc();		
			throw exc;
		}
		System.out.println(1.0*a/b);
	}
}

-->컴퓨터가 에러메세지를 출력해주기 위해 내부에서 일하는 방식이다.


finally

: 수행을 보장하는 문법

package com.bit.day09.am;

public class Ex16 {

	public static void main(String[] args) {
			int[] arr={1,2,3,4,5,6,7,8,9};
			func(arr);
	}
	
	public static void func(int[] arr){
		System.out.println("배열을 반복해서 출력하겠습니다.");
		for(int i=0; i<10; i++){
			System.out.println(arr[i]);       //ArrayIndexOutOfBoundsException
		}
		//위에서 exception이 발생하는 순간부터 일을 안한다.
		System.out.println("여기까지 입니다.");	 //그러므로 이것은 출력되지 않는다.
	}
}

package com.bit.day09.am;

public class Ex16 {

	public static void main(String[] args) {
				int[] arr={1,2,3,4,5,6,7,8,9};
				int su=3;
				boolean boo=su>0;
				try{		
					if(boo){return;}			//return이 있을지라도 finally는 반드시 수행한다.
					func(arr);
				} catch(ArrayIndexOutOfBoundsException e){
	
				}finally{						// 반드시 수행한다.
				System.out.println("메인끝");		//출력된다
				}
			}
	
	public static void func(int[] arr) throws ArrayIndexOutOfBoundsException {
		System.out.println("배열을 반복해서 출력하겠습니다.");
		for(int i=0; i<10; i++){
			System.out.println(arr[i]);
		}
		
		System.out.println("여기까지 입니다.");		//에러로 인해 수행되지 않는다.
	}
}

또한, catch를 안하고 싶으면 안해도 된다.

단 finally를 하려면 반드시 try{}finally{}를 해야한다.

package com.bit.day09.am;

public class Ex16 {

	public static void main(String[] args) {
				int[] arr={1,2,3,4,5,6,7,8,9};
				int su=3;
				boolean boo=su>0;
				try{		
					if(boo){return;}			
					func(arr);
				} finally{						//catch 없어도 됨. 
				System.out.println("메인끝");		
				}
			}
	
	public static void func(int[] arr) throws ArrayIndexOutOfBoundsException {
		System.out.println("배열을 반복해서 출력하겠습니다.");
		for(int i=0; i<10; i++){
			System.out.println(arr[i]);
		}
		
		System.out.println("여기까지 입니다.");		
	}

}

0개의 댓글

관련 채용 정보