K-Digital Training/내일배움캠프

자바 4주차

hoonssss 2023. 11. 1. 05:19
반응형
SMALL

오류 및 예외처리

오류(Error)

일반적으로 회복이 불가능한 문제

시스템 레벨에서 발생, 또는 환경적인 이유로 발생

예외(Exception)

일반적으로 회복이 가능한 문제

예외의 종류

컴파일 에러

.java -> .class 컴파일할때 발생하는 에러

자바 프로그래밍 언어의 규칙을 지키지 않았기에 발생

런타임에러

컴파일은 잘 되었지만 프로그램이 실행도중 맞닥뜨리게 되는 예외

예외처리관점에서 예외의 종류

확인된 예외(Checked Exception)

컴파일 시점에 확인하는 예외

반드시 예외처리를 해줘야하는 예외

미확인된 예외(Unchecked Exception)

런타임 시점에 확인되는 예외

throws

메서드 이름 뒤에 붙어 이 메서드가 어떠한 예외사항을 던질 수 있는 지알려주는 예약어

여러 종류의 예외사항을 적을 수 있음

throw

메서드 안에서 실제로 예외 객체를 던질 때 사용하는 예약어

실제로 던지는 예외 객체 하나와 같이 써야함

일반 메서드의 return 키워드처럼 throw문과 함께 매서드가 종료

try, catch, finally

Checked Exception(확인된 예외) 예시

public class OurBadException extends Exception { //예외클래스를 만들어서 예외를 정의한다
    public OurBadException(){
        super("위험한 행동을 하면 예외처리를 해야함");
    }
}
--------------------------------------------------------------------------------
public class OurClass {
    private final boolean just = true;

    public void thisMethodIsDagerous() throws OurBadException{
        if(just){
            throw new OurBadException();
        }
    }
}
--------------------------------------------------------------------------------
public class StudyException {
    public static void main(String[] args) {
        OurClass ourClass = new OurClass();
        try {
            ourClass.thisMethodIsDagerous();
        }catch (OurBadException e){
            System.out.println(e.getMessage());
        }finally {
            System.out.println("무조건 finally는 함");
        }
    }
}

자바의 Throwable Class

시작은 모든 객체의 Object클래스에서 시작

Throwable클래스의 자식으로 에러와 예외가 있음

에러와 예외클래스는 IOError클래스, RuntimeException클래스로 구분하여 처리

RuntimeException -> 미확인된 예외(Unchecked Exception)

IOException -> 확인된 예외(Checked Exception)

연결된예외(Chained Exception)

예외는 다른 예외를 유발할 수 있음

예외 A가 예외 B를 발생시켰다면 예외 A는 B의 원인 예외

원인 예외를 새로운 예외에 등록한 후 다시 새로운 예외를 발생시키는데, 이를 예외 연결이라고 함

연결예외 사용이유

예외를 연결하는 이유는 여러 가지 예외를 하나의 큰 분류의 예외로 묶어서 다루기 위함

checked exception을 unchecked exception으로 포장(wrapping)하는데 유용하게 사용

initCause()

지정한 예외를 원인 예외로 등록하는 메소드

getCause()

원인 예외를 반환하는 메소드

// 연결된 예외 
public class main {

    public static void main(String[] args) {
        try {
            // 예외 생성
            NumberFormatException ex = new NumberFormatException("가짜 예외이유");

            // 원인 예외 설정(지정한 예외를 원인 예외로 등록)
            ex.initCause(new NullPointerException("진짜 예외이유"));

            // 예외를 직접 던집니다.
            throw ex;
        } catch (NumberFormatException ex) {
            // 예외 로그 출력
            ex.printStackTrace();
            // 예외 원인 조회 후 출력
            ex.getCause().printStackTrace();
        }

        // checked exception 을 감싸서 unchecked exception 안에 넣습니다.
        throw new RuntimeException(new Exception("이것이 진짜 예외 이유 입니다."));
    }
}

// 출력
Caused by: java.lang.NullPointerException: 진짜 예외이유

실질적으로 예외를 처리하는 방법으로는 예외복구, 예외처리회피, 예외전환이 있음

예외복구

public String getDataFromAnotherServer(String dataPath) {
		try {
				return anotherServerClient.getData(dataPath).toString();
		} catch (GetDataException e) {
				return defaultData;
		}
}

예외처리회피하기

public void someMethod() throws Exception { ... }

public void someIrresponsibleMethod() throws Exception {
		this.someMethod();
}

예외전환하기

public void someMethod() throws IOException { ... }

public void someResponsibleMethod() throws MoreSpecificException {
		try {
			this.someMethod();
		} catch (IOException e) {
			throw new MoreSpecificException(e.getMessage());
		}
}

예외처리 회피하기의 방법과 비슷하지만, 조금더 적절한 예외를 던져주는 경우 입니다.

보통은 예외처리에 더 신경쓰고싶은 경우나, 오히려 RuntimeException처럼 일괄적으로 처리하기 편한 예외로 바꿔서 던지고 싶은 경우 사용합니다.

Generic

타입언어에서 중복되거나 필요없는 코드를 줄여주는 것 그러면서도 안전성을 해치지 않음

package week4.gen;

// 1.
public class Generic<T> {
    // 2.
    private T t;
    // 3.
    public T get() {
        return this.t;
    }

    public void set(T t) {
        this.t = t;
    }
------------------------------------------------------------------------------------------
    public static void main(String[] args) {
        // 4.
        Generic<String> stringGeneric = new Generic<>(); //<String> -> Generic<T> Generic T부분 -> String이 됨
        // 5.
        stringGeneric.set("Hello World");

        System.out.println(stringGeneric.get());

        String tValueTurnOutWithString = stringGeneric.get();

        System.out.println(tValueTurnOutWithString);
    }
}

Generic<T> 사이에 들어가는 변수명 T는 타입변수

Generic클래스는 원시타입

static멤버는 사용할 수 없음 -> 타입변수는 인스턴스변수로 간주하기 때문

다수의 타입변수를 사용할 수 있음

public class Generic<T, U, E> {
    public E multiTypeMethod(T t, U u) { ... } //E는 출력타입, T, U는 입력타임으로 선언
}


Generic<Long, Integer, String> instance = new Generic();
instance.multiTypeMethod(longVal, intVal);

와일드 카드를 통해 제네릭의 제한을 구체적으로 정할 수 있음

public class ParkingLot<T extends Car> { ... } //Car클래스와 그 자손들만 가능

ParkingLot<BMW> bmwParkingLot = new ParkingLot();
ParkingLot<Iphone> iphoneParkingLot = new ParkingLog(); // error!
  1. <? extends T> : T와 그 자손들만 사용 가능
  2. <? super T> : T와 그 조상들만 가능
  3. <?> : 제한 없음

메서드를 스코프로 제네릭을 별도로 선언 할 수도 있음

출처 : Head First Java

 
// 또는 ..
static <T> void sort(List<T> list, Comparator<? super T> c) { ... }

원래는 static에서 사용 안댐

  1. 이렇게 반환 타입 앞에 <> 제네릭을 사용한 경우, 해당 메서드에만 적용되는 제네릭 타입변수를 선언 가능
  2. 타입변수를 클래스 내부의 인스턴스 변수 취급하기 때문에 제네릭 클래스의 타입변수를 static 메서드에는 사용 할 수 없었지만, 제네릭 메소드의 제네릭 타입 변수는 해당 메소드에만 적용되기 때문에 메소드 하나를 기준으로 선언하고 사용
  3. 같은 이름의 변수를 사용했다고 해도 제네릭 메소드의 타입변수는 제네릭 클래스의 타입변수와 다름
public class Generic<T, U, E> {
		// Generic<T,U,E> 의 T와 아래의 T는 이름만 같을뿐 다른 변수
    static <T> void sort(List<T> list, Comparator<? super T> c) { ... }
}

Collection다시보기

List -> 인터페이스, 추상적 자료구조로서 순서를 가지고 있음

순서가 있고 중복을 허용한다는 점에서 Set(집합)과 구별

기본형 -> 값만 저장하고 조회, 원시타입

참조형 -> 원시타입을 추상화

Integer num = new Integer(17);  // Boxing
int n = num.intValue(); // UnBoxing
------------------------------------
Character ch = 'X'; // AutoBoxing
char c = ch; // AutoUnBoxing
반응형
LIST

'K-Digital Training > 내일배움캠프' 카테고리의 다른 글

입문 1주차/Spring  (1) 2023.11.21
자바 5주차  (1) 2023.11.01
자바 3주차  (0) 2023.10.20
자바 2주차  (0) 2023.10.20
자바 1주차  (0) 2023.10.20