public class Ex01_예외의_이해 {
public static void main(String[] args) {
/** 1) Syntax Error (문법에러) */
// java의 코딩 규칙을 지키지 않아 컴파일이 불가능한 상태
// 대체로 편집기에서 빨간색으로 강조 표시된다.
// 수정하지 않으면 컴파일 자체가 불가능
// 대입연산자가 누락되어 문법에러
// int a 100;
/** Runtime error (실행중 발생하는 에러)*/
// 문법적으로는 아무런 문제가 없지만
// 프로그램이 실행하면서 겪는 논리적 오류로 인해 발생하는 에러
// 컴파일이 되어 실행되는 과정에서 프로그램이 다운된다.
int[] k = {10,20,30};
for(int i = 0; i< 5; i++){
// 인덱스가 3인 데이터가 없으므로 i가 3일 때 에러
System.out.println(k[i]);
}
// 에러가 발생하는 순간 프로그램이 다운되므로 아래 구문은 실행 되지 못한다
System.out.println("fin : ");
}
}
/**
*
프로그램이 실행되는 과정에서 에러가 발생할 가능성이 있다면
조건문등을 사용하여 그 상황을 피해가도록 구성해야 한다.
*
*
*/
public class Ex02_고전적_예외처리 {
public static void main(String[] args) {
int[] k = {10,20,30};
// 반복문의 조건을 수정할 수 없는 상황이라고 가정할 경우
for (int i = 0; i<5; i++){
// 반복문안에서 i가 배열의 길이를 초과하지 않을 경우에만 출력하도록
// 조건문을 구성해야한다.
if (i <3){
System.out.println(k[i]);
}
}
System.out.println("fin : ");
}
}
/**
프로그래머가 대응할수 없는 경우의 발생하는 에러 예시
*
1) 파일복사를 수행하는 기능에서 하드디스크이 용량이 가득찬 경우
2) 다운로드를 수행하는 기능에서 인터넷 접속이 끊긴경우
3) USB 파일을 저장하는 과정에서 USB 연결이 강제로 해제된 경우
*
위와 같은 상황은 if문으로 해결이 어렵기 때문에
자바에서는 예외 상황에 대처하기 위한 Try ~ Catch ~ finally 문법을 제공함
*/
public class Ex03_예외처리 {
public static void main(String[] args) {
int[] k = {10,20,30};
try {
for (int i = 0; i <5; i++) {
System.out.println(k[i]);
}
} catch (Exception e) {
/** try 블록 안에서 에러가 발생할 경우 실행되는 블록 */
// try 와 catch는 꼭 명시되어야 함
// try 블록을 수행하는 과정에서 에러가 발생하면 프로그램이 다운되지 않고
// 그 즉시 catch 블록으로 제어가 이동한다
System.out.println("에러가 발생했습니다");
System.out.println("에러의 원인: " + e.getMessage());
System.out.println("====================");
e.printStackTrace();
System.out.println("====================");
} finally {
/** 에러의 발생여부에 상관없이 무조건 실행되는 블록 */
// 필요하지 않다면 생략가능
System.out.println(" 배열의 탐색 종료");
}
System.out.println("fin :)");
}
}
public class Ex04_에러상황의_세분화 {
public static void main(String[] args) {
int [] data = {100, 20, 300};
try {
// 여기서발생할 수 있는 에러상황
// 1) 배열의 index를 초과한 경우
// 2) 0으로 나눈 경우 i=0 일때
for (int i =2; i >= -1; i--){
int k = data[i];
System.out.println(k);
}
} catch (ArrayIndexOutOfBoundsException e1) {
// catch 블록을 발생할 수 있는 에러에 경우에 수에 따라 여러개를 정의 하면
// 상항별로 에러를 구분하여 대응할 수 있다.
System.out.println("배열의 인덱스를 초과했습니다.");
} catch (ArithmeticException e2) {
System.out.println("잘못된 연산 입니다.");
} catch (Exception e){
System.out.println("알수없는 에러가 발생했습니다.");
}
}
}
public class Calc {
private static Calc current;
public static Calc getInstance() { // 싱글톤 객체
if (current == null) {
current = new Calc();
}
return current;
}
private Calc() {
super();
}
// 런타임 에러가 발생할 경우 메서드 안에 직접 try ~ catch 사용
public int divied (int x, int y){
int z =0;
try {
z = x / y;
} catch (Exception e) {
System.out.println("[divied 에러] 0으로 나눌수 없습니다. ");
}
return z;
}
// throws 구문 사용
public int diviedEx (int x , int y){
return x / y;
}
}
import java.util.Scanner;
public class Ex05_예외처리 {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.print("x를 입력하세요 ");
int x = reader.nextInt();
System.out.print("y를 입력하세요 ");
int y = reader.nextInt();
reader.close();
Calc c = Calc.getInstance();
int z = c.divied(x, y);
System.out.printf("[divied] %d 나누기 %d는 %d 입니다.\n",x,y,z);
System.out.println("----------------------");
// throws가 적용된 메서드를 호출할때는 Try ~ catch가 강제된다.
int a =0;
try {
a = c.divied(x, y);
} catch (Exception e) {
System.out.println("[divied] 0으로 나눌수 없습니다.");
}
System.out.printf("[diviedEx] %d 나누기 %d는 %d 입니다\n", x,y,a);
// java에는 개발자가 예측하기 어려운 예외상황이 발생할 가능성이 있는 기능들에 대해
// 이미 모두 throws가 적용된 형태로 제공된다.
// 그러므로 개발자는 컴파일러가 강제하는 try ~ catch문을 사용함으로
// 예외상황에 자연스럽게 대비할 수 있게 된다.
}
}
/**
java에서 제공하는 에러 클래스를 상속받은 클래스
개발자가 직접 정의한 비정상적인 상황을 의미하는 클래스
*/
public class MyKorException extends Exception {
public MyKorException() {
super("국어점수가 벗어났습니다.");
}
public MyKorException (String message) {
super(message);
}
}
/**
java에서 제공하는 에러 클래스를 상속받은 클래스
- 개발자가 직접 정의한 비정상적인 상황을 의미하는 클래스
*/
public class MyMathException extends Exception {
public MyMathException() {
super("수학 범위를 벗어났습니다.");
}
public MyMathException(String message) {
super(message);
}
}
public class Student {
private String name;
private int kor;
private int math;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getKor() {
return this.kor;
}
public void setKor(int kor) throws MyKorException {
if (kor < 0 || kor > 100) {
// 이 라인에서 에러를 강제로 발생시킴
// --> throw 명령은 try ~ catch 구문으로 감싸지거나
// throw 명령을 사용하는 메서드는 throws를 통해
// 강제로 발생하는 에러에 대한 처리를 호출하는 위치로 떠넘겨야 한다.
throw new MyKorException();
}
this.kor = kor;
}
public int getMath() {
return this.math;
}
public void setMath(int math) throws MyMathException {
if(math <0 ){
throw new MyMathException("수학점수가 0보다 작습니다.");
}
if (math < 100) {
System.out.println("수학점수가 100보다 큽니다.");
}
this.math = math;
}
@Override
public String toString() {
return "{" +
" name='" + getName() + "'" +
", kor='" + getKor() + "'" +
", math='" + getMath() + "'" +
"}";
}
}
public class Ex06_사용자_정의_예외 {
public static void main(String[] args) {
Student s = new Student();
s.setName("헬로월드");
try {
s.setKor(-123);
} catch (MyKorException e) {
System.err.println("[MyKorException] >>" + e.getMessage()); // 에러메세지 출력
}
try {
s.setKor(123);
} catch (MyKorException e) {
System.err.println("[MyKorException] >>" + e.getMessage());
}
try {
s.setMath(-1);
} catch (MyMathException e) {
System.err.println("[MyMathException] >>" + e.getMessage());
}
try {
s.setMath(101);
} catch (MyMathException e) {
System.err.println("[MyMathException] >>" + e.getMessage());
}
System.out.println(s.toString());
}
}