자바에서는 컴퓨터 하드웨어의 오동작 또는 고장으로 인한 프로그램 실행 오류를
에러
라고 한다
그 외 사용자의 잘못된 조작 혹은 잘못된 코딩으로 프로그램 자체에 발생하는 오류는예외
라고 부른다
예외의 종류
와발생 원인
,해결방법
을 알아보자
자바는 모든 것이 객체로 이루어지기 때문에 예외 또한 객체로 구성되어있다.
모든 예외 클래스는 java.lang.Exception 클래스를 상속받는다.
자바의 모든 클래스가 Object를 상속받는 것과 같은 방식이다.
JVM은 프로그램을 실행하는 도중 예외가 발생하면, 해당 예외 클래스
로 객체를 생성한다. 그리고 예외 처리 코드
에서 예외 객체를 이용할 수 있도록 해준다.
Runtime Exception의 하위 클래스가 아니면 일반 예외 클래스이고, 하위 클래스이면 실행 예외 클래스이다.
예외가 발생하면 프로그램은 곧바로 종료된다는 점에서 에러외 비슷하다.
하지만 예외 처리
를 통해 프로그램을 종료하지 않고 정상 실행 상태가 유지
되도록 할 수 있다
자바는 일반 예외
의 경우 컴파일할 때 예외 처리 유무를 확인 후, 예외 처리 코드가 없다면 컴파일 오류
를 발생시켜 사전에 오류가 나지 않도록 예방한다.
UncheckedException이 있는 이유. 모든 예외가 CheckedException이라면?
- CheckedException의 경우는 예외처리 즉, try-catch를 의무로 작업하게됩니다. 코드적인 복잡도가 올라게 될것이다.
- 논리적 오류 + 예기치 않은 상황
- UncheckedException는 개발자가 개발한 논리에 의해서 발생하는 예외상황이기때문에 구분되어 처리가 되어야 한다.
예측 가능한 상황에 대한 에러.
강제적으로
개발자가 예외 처리 코드를 작성하도록 요구함어디서 어떤 예외가 나오는지 한눈에 보이지 않는다.
컴파일러가 체크하지 않기 때문에
오로지 개발자의 경험에 의해서 예외 처리 코드를 작성해야 한다. 만약 개발자가 예외 처리 코드를 넣지 않았을 경우, 해당 예외 발생 시 프로그램은 바로 종료된다.해당 객체가 null인 상태에서의 접근을 했을때 발생하는 에러로 가장 빈번하게 발생한다.
객체 참조가 없는 상태, 즉 null 값을 가지고 있는 참조 변수로 객체 접근 연산자인 도트(.)를 사용했을때 발생한다.
public class NullPointerExceptionExample {
public static void main(String[] args) {
String data = null;
System.out.println(data.toString());
}
}
배열에서 할당된 배열의 인덱스 범위를 초과해서 사용할 경우 발생하는 에러.
예를 들어 길이가 3인 int[] arr = new int[3] 배열을 선언했다고 가정하면,
해당 배열에서 사용할 수 있는 인덱스의 범위로는 위의 arr[0], arr[1], arr[2]만을 사용할 수 있는데, arr[3]이나 arr[4]등 해당 인덱스의 범위에 벗어나는 경우에는 ArrayIndexOutOfBoundsException가 발생한다.
프로그램을 개발하다가 보면 문자열로 되어있는 데이터를 숫자로 변경하는 경우가 매우 자주 발생한다.
만약 parseXXX() 메소드들을 이용하여 문자열을 숫자로 변환할 수 있지만 매개변수로 오는 문자열이 숫자로 변환이 되는 값이면 숫자를 리턴하지만, 숫자로 변환될 수 없는 문자가 온다면 java.lang.NumberFormatException을 발생시킨다.
public class NumberFormatExceptionExample {
public static void main(String[] args) {
String corretData = "100"; // 문자열 100은 숫자로 변환 할 수 있는 값이다.
String wrongData = "a100"; // 문자열 A100은 숫자로 변환 할 수 없는 값이다.
int value1 = Integer.parseInt(corretData);
int value2 = Integer.parseInt(wrongData); //NumberFormatException 발생
System.out.println(value1);
System.out.println(value2);
}
}
타입 변환(Casting)은 상위 클래스와 하위 클래스간에 발생하고 구현 클래스와 인터페이스 간에도 발생한다.
클래스 타입 변환이 가능한 경우는 아래와 같다.
상속
Animal animal = new Cat();
Parent parent = new Child(); //자동 타입 변환
Child child = (Child)parent; //강제 타입 변환
인터페이스
Vehicle vehicle = new Bus();
Vehicle vehicle = new Bus();//자동 타입 변환
Bus bus = (Bus) vehicle;//강제 타입 변환
이런 경우가 아니라, 억지로 타입변환을 시도할 경우 ClassCastException이 발생한다.
public class ClassCastExceptionExample {
static class Animal {}
static class Dog extends Animal{}
static class Cat extends Animal{}
public static void main(String[] args) {
// Cat 객체 생성
Cat cat = new Cat();
changeDog(cat);
}
public static void changeDog(Animal animal) {
Dog dog = (Dog) animal; // ClassCastException 발생 가능
}
}
ClassCastException을 발생시키지 않으려면 instanceof 연산자로 확인하는 것이 좋다
Animal animal = new Dog();
if(animal instanceof Dog){
Dog dog = (Dog) animal;
} else if(animal instanceof Cat){
Cat cat = (Cat) animal;
}
프로그램에서 예외가 발생했을 경우 프로그램이 종료되지 않고, 정상 실행을 유지할 수 있도록 예외 처리
를 한다.
예외 처리란 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것을 말한다
try-catch-finally 블록
은 생성자 내부와 메소드 내부에서 작성되어 예외처리를 할 수 있도록 해줌.
try 블록에서 예외 발생 시 예외를 처리해줄 catch블록은 위에서부터 차례로 검색
됨.
예외를 메소드를 호출한 곳으로 떠넘기는 역할
그러면 메소드를 호출하는 곳(method1)에서 try-catch 블록을 사용해서 예외처리를 함
throws 예외종류
를 작성한다리턴타입 method1(매개변수...) throws Exception1, Exception2,...{
}
사용방법
public void method2() throws ClassNotFoundExeption
try-catch
를 작성해준다예시 : 자바 API 도큐먼트
forName :
public static Class<?> forName(String className) throws ClassNotFoundException
---
//forName 메소드 사용 : try-catch블록을작성한다
public class ThrowsExample{
try{
findClass();
} catch (ClassNotFoundException e) {
System.out.println("클래스가 존재하지 않습니다");
}
}
//forName 메소드 선언 : ClassNotFoundException 예외를 throws 처리한다
public static void findClass() throws ClassNotFoundException {
Class clazz = Class.forName("java.lang.String2");
}
public class XXXException extends [Exception | RuntimeException] {
public XXXException(){}
public XXXException(String message){super(message);}
}
public void method() throws XXXException {
throw new XXXException("메시지");
}
throw
throws
try {
// 예외를 발생시키는 코드
} catch (IOException e) {
// IOException을 처리하면서 다른 예외가 발생하는 상황을 가정한다.
RuntimeException runtimeException = new RuntimeException
("An error occurred while handling IOException");
runtimeException.initCause(e);
throw runtimeException;
}
참고
혼자공부하는자바, 이것이 자바다
https://rebeccacho.gitbooks.io/java-study-group/content/chapter8.html
https://imasoftwareengineer.tistory.com/86
https://slidesplayer.org/slide/15489240/