Test140~Test151
//자바의 정석 p.414
//어려워도 당황하지마! 원래그래
① 잘못된 문법을 사용하거나 변수 등을 정의하지 않은 상태에서
사용함으로써 컴파일 단계에서 발생하는 문법적인 오류
② 프로그램을 실행하는 과정에서 발생되는 런타임 오류
로 나눌 수 있다.
개발자가 문제 분석을 잘못하거나 실수에 의해 엉뚱한 결과를 가져오게 되는 논리적인 오류와
시스템 이상에서 발생되는 시스템 오류, 그리고
프로그램 실행 중 발생되는 비정상적인 상황을 의미하는 예외사항(Exception)이 있다.
예를 들어,
→ 어떤 수를 0으로 나누거나...
→ 배열 첨자를 벗어나는 상황이 발생하거나...
→ 존재하지 않은 파일을 오픈하여 읽어들인다거나...
==> 개발자가 이런 예외 사항이 발생할 경우를 미리 예측하여
적절히 대응하기 위한 절차를 구현하도록 문법을 정리해 놓은 것.
예.외.처.리.
※ 정리해 놓은 문법~!!!(→ Exception 클래스)
예외는 프로그램 실행 중에 발생할 수 있는 명령어의 정상적인 흐름을 방해하는 이벤트로 자바에서 예외는 하나의 오브젝트(Object, 객체)이다.
프로그램 실행 중에 메소드 안에서 오류가 발생하게 될 경우, 메소드는 그 오류에 해당하는 예외 오브젝트를 만들고 그것을 자바 런타임 시스템(Runtime System)에 전달해 준다.
자바에서의 모든 예외는 Throwable 클래스나 Throwable 클래스의 하위 클래스를 상속받아 사용한다.
Throwable 클래스는 예외를 설명하는 문장이나 예외가 발생할 때의 프로그램의 상태에 관한 정보를 포함하고 있다.
Throwable 클래스에서 파생된 클래스
▪ Exception 클래스
Exception 예외 클래스는 일반적으로 프로그래머에 의해
복원될 수 있는 예외 상황으로
메소드가 실행 중에 던지는 예외를 가리킨다.
▪ Error 클래스
심각한 예외의 형태로 개발자가 복원할 수 없는 형태의 예외이다.
checked exception
메소드 내에서 예외가 발생한 경우 메소드를 정의할 때 『throws』문에 메소드 내에서 발생할 수 있는 예외들을 명시해주거나 또는 그 예외를 『try~catch』해서 처리해주어야만 하는 예외이다.
컴파일러가 컴파일 하는 과정에서 『checked exception』이 『throws』 되는가의 여부 혹은 『try~catch』되는지의 여부를 판단하여 프로그램에서 예외를 어떤 방식으로 처리하지 않으면 컴파일 자체가 불가능하다.
unchecked excepion
사전에 처리하지 않아도 컴파일러가 체크하지 않은 런타임 시에 발생할 수 있는 예외이다.
String toString()
: Throwable 각각에 대한 설명을 문자열 형태로 반환한다.
void printStackTrace(printStream s)
void printStackTrace(printWriter w)
: 표준 출력 스트림에 스택 호출 목록을 마지막 메소드부터 출력한다.
.getMessage() = 에러 이벤트와 함께 들어오는 메세지를 출력한다.
.toString() = 에러 이벤트의 toString()을 호출해서 간단한 에러 메시지를 확인한다.
.printStackTrace() = 에러 메세지의 발생 근원지를 찾아서 단계별로 에러를 출력한다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Test143_1
{ //---------[예외 처리하는 방법 ①]: throws IOException로 던지기
public static void main(String[] args) throws IOException
{
//BufferdReader 인스턴스 생성
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 주요 변수 선언
int a, b, c;
//-----------------[예외 처리하는 방법 ②] : try-catch 구문에 문제될 부분 넣기
/*
try
{
System.out.print("첫 번째 정수 입력 : ");
a = Integer.parseInt(br.readLine());
System.out.print("두 번째 정수 입력 : ");
b = Integer.parseInt(br.readLine());
//error: unreported exception IOException; must be caught or declared to be thrown
// ---------------------
c = a + b;
System.out.println("결과 : " + c);
}
catch (IOException e) //IOException을 이름붙여서(e)
{
// IOExcepiton → checked exception
//-- 메소드를 정의하는 과정에서 throws 한 예외
// 잡아내거나 던지지 않을 경우 컴파일 에러 발생.
System.out.println(e.toString()); //별도로 처리하겠다! 여기선 toString 함
}
*/
//----------------- [예외 처리하는 방법 ③] : 숫자형태 이외에 값 입력
/*
try
{
System.out.print("첫 번째 정수 입력 : ");
a = Integer.parseInt(br.readLine());
System.out.print("두 번째 정수 입력 : ");
b = Integer.parseInt(br.readLine());
c = a + b;
System.out.println("결과 : " + c);
}
catch (IOException e1) //IOException을 이름붙여서(e)
{
// IOExcepiton → checked exception
//-- 메소드를 정의하는 과정에서 throws 한 예외
// 잡아내거나 던지지 않을 경우 컴파일 에러 발생.
System.out.println(e1.toString()); //별도로 처리하겠다! 여기선 toString 함
}
catch(NumberFormatException e2)
{
System.out.println(e2.toString());
System.out.println("숫자 형태의 데이터를 입력해야 합니다~!!!");
}
// catch 되서 처리되고 있음!
//첫 번째 정수 입력 : abc
//java.lang.NumberFormatException: For input string: "abc"
//숫자 형태의 데이터를 입력해야 합니다~!!!
//계속하려면 아무 키나 누르십시오 . . .
*/
//----------------- [예외 처리하는 방법 ④] : catch 안에 한번에 처리 e.printStackTrace()사용
/*
try
{
System.out.print("첫 번째 정수 입력 : ");
a = Integer.parseInt(br.readLine());
System.out.print("두 번째 정수 입력 : ");
b = Integer.parseInt(br.readLine());
//error: unreported exception IOException; must be caught or declared to be thrown
// ---------------------
c = a + b;
System.out.println("결과 : " + c);
}
catch (IOException e) //IOException을 이름붙여서(e)
{
System.out.println(e.toString()); //별도로 처리하겠다! 여기선 toString 함
System.out.println(e.getMessage());
System.out.println("pringStackTrace...");
e.printStackTrace();
}
*/
//----------------- [예외 처리하는 방법 etc...]s : finally사용
try
{
System.out.print("첫 번째 정수 입력 : ");
a = Integer.parseInt(br.readLine());
System.out.print("두 번째 정수 입력 : ");
b = Integer.parseInt(br.readLine());
//error: unreported exception IOException; must be caught or declared to be thrown
// ---------------------
c = a + b;
System.out.println("결과 : " + c);
}
catch (IOException e) //IOException을 이름붙여서(e)
{
// IOExcepiton → checked exception
//-- 메소드를 정의하는 과정에서 throws 한 예외
// 잡아내거나 던지지 않을 경우 컴파일 에러 발생.
System.out.println(e.toString()); //별도로 처리하겠다! 여기선 toString 함
}
finally //check~!!!
{
// 예외가 발생하거나 발생하지 않거나...
// 언제나 실행되는 영역~!!!
System.out.println("고생 많으셨습니다. 점심 맛있게 먹읍시다.");
}
}
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Test144
{
private String[] date = new String[3];
public void proc() throws IOException //-- readLine() 때문에 throws 입력!
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str;
int n = 0;
System.out.print("이름 입력(종류:ctrl+z) : ");
// 원래는 오른쪽부터인데 괄호로 묶은것 먼저
while ((str = br.readLine()) != null) //-- readLine() 때문에 throws 안해주면 에러 발생!
{ //-------- == ctrl+z
date[n++] = str;
System.out.print("이름 입력(종류:ctrl+z) : ");
}
System.out.println("입력된 내용...");
for(String s : date)
{
if(s != null)
{
System.out.println(s);
}
}
}
public static void main(String[] args) throws IOException
{
Test144 ob = new Test144();
ob.proc();
}
}
// 배열이 3갠데 4개 넣으려고하니까 에러발생 -> 이건 unchecked excepion
//Test144같은데 try-catch사용 -> 내부적으로 예외를 잡아버려서 throws IOException을 메인에 안해도 됨!!
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Test145
{
private String[] date = new String[3];
public void proc() //throws IOException //-- readLine() 때문에 throws 입력!
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str;
int n = 0;
try
{
System.out.print("이름 입력(종류:ctrl+z) : ");
// 원래는 오른쪽부터인데 괄호로 묶은것 먼저
while ((str = br.readLine()) != null) //-- readLine() 때문에 throws 안해주면 에러 발생!
{ //-------- == ctrl+z
date[n++] = str;
System.out.print("이름 입력(종류:ctrl+z) : ");
}
System.out.println("입력된 내용...");
for(String s : date)
{
if(s != null)
{
System.out.println(s);
}
}
}
catch (IOException e)
{
System.out.println(e.toString());
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("예외 발생~!!!");
System.out.println("getMessage : " + e.getMessage());
System.out.println("toString : " + e.toString());
System.out.println("printStackTrace...........");
System.out.println();
//이름 입력(종류:ctrl+z) : 정효진
//이름 입력(종류:ctrl+z) : 김효진
//이름 입력(종류:ctrl+z) : 박효짐
//이름 입력(종류:ctrl+z) : 마효진
//예외 발생~!!!
//getMessage : 3
//toString : java.lang.ArrayIndexOutOfBoundsException: 3
//printStackTrace...........
//계속하려면 아무 키나 누르십시오 . . .
}
}
public static void main(String[] args) //throws IOException
{
Test145 ob = new Test145();
ob.proc();
}
}
class Demo
{
private int value; //기본적으로 0으로 초기화 되니까 -3 넣어도 0나옴
public void setValue(int value)
{
if(value<=0)
return; //-- 종료 → 메소드 종료
this.value = value;
}
public int getValue()
{
return value;
}
}
public class Test146
{
public static void main(String[] args)
{
Demo ob = new Demo();
ob.setValue(-3);
int result = ob.getValue();
System.out.println(result);
}
}
class Demo2
{
private int value;
public void setValue(int value) throws Exception //check~!!! Exception 은 lang패키지에 있어서 import생략 가능한~!
{
if(value<=0)
{
// 예외 생성(발생) - 폭발물 제작을 여기서 한 것!
throw new Exception("value 는 0보다 작거나 같을 수 없습니다.");
// throw 예외를 발생시킬때 사용하는 키워드!! ==> 이렇게 실행하면 에러! throws Exception 작성해줘야함!!
}
this.value = value;
}
public int getValue()
{
return value;
}
}
public class Test147
{
public static void main(String[] args) //throws Exception //check~!!! 이렇게 해주던지 아니면 try-catch로 잡아내!
{
Demo2 ob = new Demo2();
try
{
ob.setValue(-3);
int result = ob.getValue();
System.out.println(result);
}
catch (Exception e) // checked Exception
{
System.out.println(e.toString());
}
}
}
/*
java.lang.Exception: value 는 0보다 작거나 같을 수 없습니다.
계속하려면 아무 키나 누르십시오 . . .
*/
public class Test148
{
public static void main(String[] args)
{
Test148 ob = new Test148();
try
{
int a = ob.getValue(-2); // ⑥ 예외 발생
System.out.println("a : " + a);
}
catch (Exception e) // ⑦ 예외 잡아내기
{
System.out.println("ⓑ printStackTrace.......");
e.printStackTrace();
}
}
public int getData(int data) throws Exception
{
if (data<0)
throw new Exception("date 가 0보다 작습니다.");
// ① 예외 발생 --> 그래서 던지기로 함(throws Exception) -> 이러면 getValue 로 떨어짐
return data + 10;
}
public int getValue(int value) throws Exception
{
int a = 0;
try
{
a = getData(-2); // ② 예외발생 -> 그래서 예외를 catch로 잡음 근데 왜?? throws Exception을 썼나?
}
catch (Exception e) // ③ 예외 잡아내기
{
// ④ 잡아낸 예외에 대한 처리
System.out.println("ⓐ printStackTrace............");
e.printStackTrace();
// ⑤ 잡아낸 예외를 다시 던지기
throw e; //이거 주석하면 throws Exception 없어도됨
//-- 주석 처리 시(즉, 잡아낸 예외를 다시 던지지 않을 경우)
// main() 메소드의 예외 처리 구문은 수행되지 않게 된다.
}
return a;
}
}
/*
ⓐ printStackTrace............
java.lang.Exception: date 가 0보다 작습니다.
at Test148.getData(Test148.java:29)
at Test148.getValue(Test148.java:41)
at Test148.main(Test148.java:15)
ⓑ printStackTrace.......
java.lang.Exception: date 가 0보다 작습니다.
at Test148.getData(Test148.java:29)
at Test148.getValue(Test148.java:41)
at Test148.main(Test148.java:15)
계속하려면 아무 키나 누르십시오 . . .
*/
public class Test149
{
public int getValue(int value) throws Exception // ⑦ 예외 던지기(파란 폭발물)
{
int a = 0;
try
{
a = getData(-2); //③ 예외 발생
} // 빨간 폭발물
catch (Exception e) //④ 예외 잡아내기
{ // 빨간 폭발물
// ⑤ 예외 처리(빨간 폭발물)
System.out.println("printStackTrace..............");
e.printStackTrace();
// ⑥예외 생성
throw new Exception("value 가 음수입니다.");
// 아까는 같은 e던지는 거였는데 지금은 새로운 예외 발생!
// (파란 폭발물)
}
return a;
}
public int getData(int data) throws Exception //② 예외 던지기
{ // 빨간 폭발물
if(data<0)
throw new Exception("date 가 0 보다 작습니다."); //① 예외 발생
// 빨간 폭발물
return data + 10;
}
public static void main(String[] args) // ⑨
{
Test149 ob = new Test149();
try
{
int a = ob.getValue(-1); //⑧ 예외 발생 //파란 폭발물
System.out.println("a: " + a);
}
catch (Exception e) // ⑨ 예외 잡아내기 //파란 폭발물
{
// ⑩ 예외 처리(파란 폭발물)
System.out.println("printStackTrace..............");
e.printStackTrace();
}
}
}