import java.io.FileReader;
public class CheckedException {
public static void main(String[] args) {
FileReader file = new FileReader("something.txt");
}
}
컴파일 에러 - 에외 처리 필수
1-2. 예외 처리 후
예외처리1) try-catch문 사용
import java.io.FileNotFoundException;
import java.io.FileReader;
public class CheckedException {
public static void main(String[] args) {
try {
FileReader file = new FileReader("something.txt");
}catch(FileNotFoundException e) {
e.printStackTrace();
}
}
}
예외처리2) throws 사용
import java.io.FileNotFoundException;
import java.io.FileReader;
public class CheckedException {
public static void main(String[] args) throws FileNotFoundException {
FileReader file = new FileReader("something.txt");
}
}
2. Unchecked Exception
import java.io.FileReader;
import java.io.IOException;
public class UncheckedException{
public static void main(String[] args) {
try{
FileReader file = new FileReader("hello.txt");
file = null;
file.read(); //NullPointerException 발생
} catch (IOException e) {
//Alternate logic
e.printStackTrace();
}
}
}
실행 결과
--> Checked Exception과 달리 NullPointerException에 대한 예외 처리를 하지 않았음에도 컴파일이 되고 실행됨
예외 발생시키고 처리해보기 (Java11 기준)
1. 실행 예외 : 0으로 나눴을 때 --> ArithmeticException 발생
ArithmeticException클래스의 상속 관계
import java.util.Scanner;
public class DivdeByZero {
public static void main(String[] args) {
Scanner kbd = new Scanner(System.in);
int dividend; //나눠지는 수
int divisor; //나누는 수
while(true) {
System.out.print("나눠지는 수 입력 : ");
dividend = kbd.nextInt();
System.out.print("나누는 수 입력 : ");
divisor = kbd.nextInt();
try {
System.out.println("몫은 " + dividend/divisor); //divisor 0 입력 시 예외 발생
break; //올바른 입력 시 반복문 종료
}catch(ArithmeticException e) { //예외 처리
System.out.println("divisor는 0이 될 수 없음 다시 입력하셈");
//e.printStackTrace(); //예외 발생 코드 추적 내용 확인
}
}
}
}
실행 결과
2. 실행 예외 : 범위를 벗어난 배열의 접근 --> ArrayIndexOutOfBoundsException 발생
ArrayIndexOutOfBoundsException클래스의 상속 관계
public class ArrayIndexOut {
public static void main(String[] args) {
int[] intArr = new int[3];
try {
for(int i = 0; i<=intArr.length; i++) {
intArr[i] = i*i;
System.out.println(intArr[i]);
}
}catch(ArrayIndexOutOfBoundsException e) { //예외 처리
e.printStackTrace();
System.out.println("배열의 인덱스 범위를 벗어났습니다.");
}
}
}
실행 결과
3. 실행 예외 : 입력 오류 시 --> java.util.InputMismatchException 발생
InputMismatchException클래스 상속 관계
import java.util.InputMismatchException; //java.util 패키지 이므로 import 해줘야 함
import java.util.Scanner;
public class InputMismatch {
public static void main(String[] args) {
Scanner kbd = new Scanner(System.in);
System.out.println("정수 3개를 입력하세요.");
int sum = 0, n=0;
for(int i = 0; i<3; i++) {
System.out.print(i + ">>");
try {
n = kbd.nextInt(); //정수 입력 -> 정수 이외의 값 입력 시 InputMismatchException 발생
}catch(InputMismatchException e) {
System.out.println("정수가 아닙니다. 다시 입력!");
System.out.println(kbd.next()); //입력 스트림에 있는 정수가 아닌 토큰 버림
i--;
continue;
}
sum += n;
}
System.out.println("합은 " + sum);
}
}
실행 결과
4. 실행 예외 : 정수가 아닌 문자열을 정수로 변환할 때 --> NumberFormatException 발생
NumberFormatException클래스 상속 관계
public class NumberFormat {
public static void main(String[] args) {
String[] stringNum = {"03", "25", "3.1515", "28"};
int i = 0; //catch블록에서 i 값 사용하기 위해 try 블록 밖에서 선언해줌
try {
for(i=0; i<stringNum.length; i++) {
int j = Integer.parseInt(stringNum[i]);
System.out.println("변환된 값 : " + j);
}
}catch(NumberFormatException e) {
System.out.println(stringNum[i]+ "는 정수로 변환할 수 없습니다.");
}
}
}
실행 결과
추가 정리
void printStackTrace()
java.lang.Throwable 클래스에 정의된 메소드로 Exception클래스는 Throwable 클래스를 상속 받으므로 Exception 클래스의 모든 하위 클래스들은 해당 메소드 사용 가능함
메서드 기능 : 예외 발생 코드 추적한 내용을 모두 콘솔에 출력 --> 프로그램 테스트하면서 오류 찾을 때 유용함
사용 예시 :try-catch 문으로 예외처리 시 예외 발생 코드 추적한 내용은 나오지 않는데, printStackTrace()를 사용하면 예외 발생 코드 추적한 내용을 콘솔에 출력해줌
try 블록 내의 변수
try 블록 내에 선언된 변수는 해당 블록 내에서만 알 수 있어서 catch 블록이나 finally 블록에서도 사용하려면, try 블록 외부에 미리 선언해두어야 함
사용 예시 :
try 블록 내에 선언된 변수 i 를 catch 블록에서 사용했으므로 컴파일 에러 발생