예외처리
- 개발자가 예측 가능한 문제 상황에 대한 처리 방법을 명시해두는 것
- 프로세스 중 어떤 부분에서 문제가 생겼는지 파악하기 위해 사용한다.
- IO 관련해서는 예외처리가 필수이다.
형식
- 자식클래스는 부모클래스로 치환되기 때문에, 자식클래스를 부모클래스보다 위쪽에 배치해야 한다.
try {
} catch (예외클래스타입1 변수명){
} catch (예외클래스타입2 변수명){
} finally {
}
예외 발생 이후의 명령은 실행되지 않는다.
try {
System.out.println(3);
System.out.println(0/0);
System.out.println(4);
} catch (ArithmeticException e) {
System.out.println(5);
}finally {
System.out.println(6);
}
3
5
6
예외 만들어 던지기
- new Exception - 예외 객체 생성, 인자로 넣어준 메시지가 예외메시지가 된다.
- throw - 예외 던지기(발생시키기)
try {
throw new Exception("고의로 예외발생");
} catch (Exception e) {
System.out.println("에러 메시지: " + e.getMessage());
e.printStackTrace();
}
System.out.println("프로그램 정상 종료");
숫자 게임 - 예외처리
- 예외가 발생할 수 있는 코드부분에만 try를 씌운다.
int answer = (int)(Math.random() * 100) + 1;
int input = 0;
int count = 0;
do {
count++;
System.out.println("1~100사이의 값을 입력하세요 : ");
try {
input = new Scanner(System.in).nextInt();
} catch (InputMismatchException e) {
System.out.println("입력이 잘못됨");
continue;
}
if (input == answer) {
System.out.println("정답!");
System.out.println("시도 횟수 : " + count);
break;
} else if (input < answer) {
System.out.println("up");
System.out.println("시도 횟수 : " + count);
continue;
} else if (input > answer) {
System.out.println("down");
System.out.println("시도 횟수 : " + count);
continue;
}
} while (true);
PrintStackTrace 의 stack - 자료구조
Queue
- First In First Out (선입선출)
Stack
- Last In First Out (후입선출)
- 일반적인 프로그램, 네트워크의 자료 구조
메소드를 호출한 사람에게 예외 던지기(책임전가)
public class Rectangle {
private int width;
private int heigth;
public Rectangle(int width, int height) throws Exception {
if (width <= 0 || height <= 0) {
throw new Exception("넓이 또는 높이의 값이 잘못되었습니다");
}
this.width = width;
this.heigth = height;
}
int getArea() {
return width *heigth;
}
}
- main 에서 메소드 호출하기
- throw 로 JVM에게 책임전가하거나
- try - catch 로 예외를 처리해주어야 한다.
public class RectangleMain {
public static void main(String[] args) {
Rectangle r = null;
try {
r = new Rectangle(5, 98);
} catch (Exception e) {
System.out.println(e.getMessage());
}
int area = r.getArea();
System.out.println("넓이: " + area);
}
}
사용자 정의 예외 만들기
- 예외 클래스 직접 만들기
- Exception을 상속하면 Catch에 사용할 수 있는 예외 클래스가 된다.
public class AgeInputException extends Exception {
public AgeInputException() {
super("유효하지 않은 나이가 입력되었습니다.");
}
}
public class NameLengthException extends Exception {
String name;
public NameLengthException(String name) {
super("잘못된 이름이 입력되었습니다.");
}
public void showWrongName() {
System.out.println(this.name + "은(는) 잘못된 이름입니다.");
}
}
public class PersonalInfo {
String name;
int age;
public PersonalInfo(String name, int age) {
this.name = name;
this.age = age;
}
public void showPersonalInfo() {
System.out.println("이름: " + this.name);
System.out.println("나이: " + this.age);
}
}
import java.util.Scanner;
public class UserExceptionMain {
public static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
try {
PersonalInfo info = readPersonalInfo();
info.showPersonalInfo();
} catch (AgeInputException e1) {
e1.printStackTrace();
} catch (NameLengthException e2) {
e2.showWrongName();
e2.printStackTrace();
}
}
public static PersonalInfo readPersonalInfo() throws AgeInputException, NameLengthException {
String name = readName();
int age = readAge();
return new PersonalInfo(name, age);
}
public static int readAge() throws AgeInputException{
System.out.println("나이 입력: ");
int age = sc.nextInt();
if (age < 0) {
throw new AgeInputException();
}
return age;
}
public static String readName() throws NameLengthException {
System.out.println("이름 입력: ");
String name = sc.nextLine();
if (name.length() < 2 || name.length() > 4) {
throw new NameLengthException(name);
}
return name;
}
}
printStackTrace
- 호출된 메소드 순서대로 제일 아래쪽부터 쌓인다.
exception.AgeInputException: 유효하지 않은 나이가 입력되었습니다.
at exception.UserExceptionMain.readAge(UserExceptionMain.java:41)
at exception.UserExceptionMain.readPersonalInfo(UserExceptionMain.java:32)
at exception.UserExceptionMain.main(UserExceptionMain.java:19)
이너 클래스, Inner Class, Nested Class
class A {
class B {
}
}
Outer - Inner 예제
public class Outer {
class Inner {
void jababa() {
System.out.println("잡아바");
}
}
}
public class OuterMain {
public static void main(String[] args) {
new Outer().new Inner().jababa();
}
}
PiggyBank 예제
public class PiggyBank {
int total;
Slot slot;
public PiggyBank() {
total = 0;
slot = new Slot();
}
class Slot {
void put(int amount) {
total += amount;
}
}
}
public class PiggyBankMain {
public static void main(String[] args) {
PiggyBank bank1 = new PiggyBank();
PiggyBank bank2 = new PiggyBank();
PiggyBank bank3 = new PiggyBank();
bank2.slot.put(1000);
bank3.slot.put(2000);
bank3.slot.put(2000);
System.out.println("첫 번째 저금통: " + bank1.total);
System.out.println("두 번째 저금통: " + bank2.total);
System.out.println("세 번째 저금통: " + bank3.total);
}
}