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가 뜬다.
}
}
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();
}
}
그러므로 예외처리를 강제하지 않는다. (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);
}
}
반면 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("여기까지 입니다.");
}
}