프로그램에서 오류가 발생하는 상황은 두가지이다.
하나는 프로그램 코드 작성 중 실수로 발생하는 컴파일 오류(Compile error)이고, 다른 하나는 실행 중인 프로그램이 의도하지 않은 동작을 하거나 프로그램이 중지되는 실행 오류(Runtime error)이다.
버그(Bug)라고 한다.실제 서비스를 제공하고 있는 프로그램의 경우 오류가 생기면 서비스가 중지되므로 문제가 심각해진다. 또한 실행 중에 오류가 발생하면 그 상황을 재현하여 테스트해야 하는데, 실제 시스템이나 서비스가 운영 중인 경우에는 쉽지가 않다. 따라서 로그(log)분석을 통해 원인을 찾을 수 있도록 프로그램을 개발할 때 로그를 정확하게 남기는 것이 중요하다.
🔑 로그란? 소프트웨어 실행 중에 발생하는 여러 상황을 기록한 내용으로서 주로 파일에 기록한다. 이러한 파일을 로그파일(log file)이라고 한다.
오류(error)예외(Exception) - 프로그램에서 제어가능
오류 클래스의 계층 구도
Java 최상위 클래스인 Object를 기준으로 Throwable 클래스가 있고, throwable 클래스를 상속받는 Exception, Error클래스가 있다.
Checked Exception
복구 가능성이 있는 예외 이므로 반드시 예외를 처리하는 코드를 함께 작성해야 한다.catch 문으로 잡거나 throws를 통해 메소드 밖으로 던질 수 있다. 만약 예외를 처리하지 않으면 💣컴파일 에러가 발생한다.복구 가능성이 없는 예외들이므로 컴파일러가 예외처리를 강제하지 않는다. 그래서 Unchecked Exception라고 하는데, Error와 마찬가지로 에러를 처리하지 않아도 컴파일 에러가 발생하지 않는다. 즉, 런타임 예외는 예상치 못했던 상황에서 발생하는 것이 아니므로 굳이 예외처리를 강제하지는 않는다.try{
예외가 발생할 수 있는 코드 부분
} catch(처리할 예외 타입e e){
try 블록 안에서 예외가 발생했을 때 예외를 처리하는 부분
}
try - catch문 사용하기
public class ArrayException {
public static void main(String[] args) {
int[] arr =new int[5];
try { // 오류가 날 수 있는 녀석을 try 안에 선언
for(int i = 0; i <= 5; i++){
arr[i] =i;
System.out.println(arr[i]);
}
}catch(IndexOutOfBoundsException e) {
System.out.println("예외 처리함");
}catch(NullPointerException e) {
System.out.println("빈값 처리함");
}catch(Exception e) {
System.out.println("예상 못한 예외 처리함");
}
System.out.println("프로그램 정상 종료");
}
}
try{
예외가 발생할 수 있는 부분
}catch(처리할 예외 타입 e){
예외를 처리하는 부분
}finally{
항상 수행되는 부분
}
throws 예외 선언을 하지 않아도 된다RuntimeException(UncheckedException)을 처리하기 위해 쓰는 방식package j21_예외;
public class CustomErrorException extends RuntimeException {
public CustomErrorException() {
System.out.println("내가 만든 예외 생성");
}
public CustomErrorException(String message) {
super(message); //super(); -> RuntimeException 부모클래스에서
}
}
package j21_예외;
public class CustomExceptionMain {
public static void main(String[] args) {
try {
throw new CustomErrorException("뭔가 문제가 있음");
} catch (CustomErrorException e) {
String message = e.getMessage();
System.out.println(message);
}
System.out.println("프로그램 종료");
}
}
package j22_익명클래스;
public interface Calculator {
public int cal(int x, int y); //설계도
}
package j22_익명클래스;
public class Addition implements Calculator {
@Override
public int cal(int x, int y) {
return x + y;
}
}
package j22_익명클래스;
public class Main {
public static void main(String[] args) {
Calculator c1 = new Addition();
System.out.println(c1.cal(10, 20));
System.out.println("===================================");
Calculator c2 = new Calculator() {
@Override
public int cal(int x, int y) { // 일회성은 익명클래스
return x-y;
}
};
System.out.println(c2.cal(20, 10));
}
}
📍 익명 클래스는 새로운 클래스를 익명으로 사용하는 것이 아니라, 이미 정의되어 있는 클래스의 멤버들을 재정의(오버라이딩) 하여 사용할 필요가 있을 때,그것이 일회성으로 이용될 떄의 사용 기법 즉, 익명 클래스는 부모 클래스의 자원을 일회성으로 재정의하여 사용하기 위한 용도
📍 익명 클래스는 이름이 없기 때문에 생성자를 가질 수 없으며, 가질 필요도 없다.