Day 40

ChangWoo·2023년 5월 15일
0

자바의 정석

목록 보기
40/71
post-thumbnail

ch 8-18 연결된 예외

연결된 예외(chained exception)

한 예외가 다른 예외를 발생시킬 수 있다.
예외 A가 예외 B를 발생시키면, A는 B의 원인 예외(cause exception)

  • Throwable initCause(Throwable cause) : 지정한 예외를 원인 예외로 등록 (int cause로 두 예외를 연결 시켜준다. / 예외A를 얻을 수 있다.)
  • Throwable getCause() : 원인 예외를 반환 (지정된 예외를 받는다.)
  • Throwable = Exception과 Error의 조상 / 그래서 Exception으로 보면 된다.
  • cause = 원인 예외를 저장하기 위한 iv
  • 하나의 예외 안에 또 다른 예외를 포함시키는 것
  • Install을 위한 메서드라고 가정했을 때,
  • StartInstall로 Install을 시작하는데, 저장공간이 부족해서 SpaceException이 발생
  • try-catch로 처리하는데 새로운 예외 B를 생성한다. (예외B=ie)
  • ie.initCause(e)에서 initCause(e)는 예외A, ie는 예외B
  • 예외A를 예외B에 포함시킨다.(initCause로)
  • 예외A와 예외B는 연결된예외

연결된 예외 사용 이유 1

여러 예외를 하나로 묶어서 다루기 위해서 (체계적인 예외를 포괄적인 예외로 변경하기 위해)

  • 여러 예외를 정의할 수 있다. 그런데, 예외가 너무 많으면 catch블럭이 많아진다는 단점이 있다.
  • 그래서 하나의 catch 블럭으로 사용하기 위해서 예외를 연결한다.
try {
	install();
} catch(InstallException e) {
	e.printStackTrace();
} catch(Exception e) {
	e.printStackTrace();
}
  • 위와 같이 하나로 연결하기 위해서는 catch블럭들은 Install 메서드 안으로 넣어야 한다.
  • 메서드가 설치를 하다가 예외가 발생하면, 그 예외를 InstallException에 넣어준다.
  • InstallException을 만들고 그 안에 spaceException을 넣어준다.
  • 그리고 그 예외를 호출한 메서드에 던져준다.
  • 그러면, InstallException 하나만 사용해도 된다.
  • caused by : ~ 가 원인 예외가 된다.
  • 세부적인 예외처리를 메서드 안으로 감출 수 있어서 조금 더 예외처리가 간단해진다.

연결된 예외 사용 이유 2

checked예외를 unchecked예외로 변경하려 할 때

  • checked 예외 = Exception의 자손, 필수처리
  • unchecked 예외 = RuntimeException의 자손, 선택처리
  • 결국, 필수처리를 선택처리로 변경할 때 사용한다.
  • 예외선언은 Exception 자손만 한다. (RuntimeException 자손도 가능은 하지만 잘 안한다.)
  • 그래서 SpaceException 과 MemoryException은 Exception의 자손으로 예외 필수처리(checked예외)다.
  • 그런데, SpaceException을 선택처리(unchecked예외)로 바꾸고 싶을 때, 이미 SpaceException이 많이 사용되고 있기 때문에 자손을 바꾸는게 힘들다.
  • 그래서 연결된 예외를 이용해서 변경한다.
  • SpaceException을 RuntimeException에 포함시킨다. (위의 예시에서는 MemoryException을 연결시켰다.)
  • RuntimeException에 MemoryException을 원인 예외로 등록했다.
  • initCause 대신 RuntimeException 이라는 생성자를 사용했다.
  • 실제로 발생하는 예외는 MemoryException이지만, RuntimeException으로 감싼 것이다.
  • checked 예외를 사용하면, try-catch를 사용해야 하기 때문에 unchecked 예외를 변경하는 것이다.

ch 9-1~3 Object클래스, equals()

Object클래스

모든 클래스의 최고 조상. 오직 11개의 메서드만을 가지고 있다.
notify(),wait()등은 쓰레드와 관련된 메서드이다.

  • finalize : 생성자와 반대되는 메서드로 객체가 소멸될 때 자동으로 호출된다.
  • clone : 객체의 복사본 생성시에 사용
  • equals : 객체비교시 사용
  • Class getClass : 클래스 정보를 반환한다.
  • Class : 클래스의 정보를 담기 위한 클래스 / 1.객체생성 2.객체정보 획득의 역할을 한다.
  • ReflectionAPI : Java의 기본 API로 객체생성, 객체활용 등의 역할을 한다.
  • private은 public으로 오버라이딩 해줘야 한다.

Object(Object obj)

객체 자신(this)과 주어진 객체(obj)를 비교한다. 같으면 true, 다르면 false
Object클래스의 equals()는 객체의 주소를 비교(참조변수 값 비교)

public boolean equals(Object obj) {
	return (this==obj); // 주소비교 (주소가 같아야 true)
}

  • value라는 클래스가 있을 때, value라는 iv를 하나 가지고 있다.
  • 값이 같은 value를 2개 만들고 equals를 통해 값을 비교해서 println으로 출력하면, v1과 v2는 서로 다른 객체(주소가 서로 다르기 때문에)
  • 서로 다른 두 객체는 항상 주소가 다르다.
  • v1 = this / v2 = obj
  • v1 == v2 -> 0x1234 == 0x2345 -> false

equals(Object obj)의 오버라이딩

인스턴스 변수(iv)의 값을 비교하도록 equals()를 오버라이딩해야 한다.

  • cv : 객체마다 공통 (공용 값)
  • iv : 객체마다 다름 (개별 값)
  • Person 객체를 2개 만들었는데, 값이 같다.
  • 서로 다른 두 객체이므로 주소를 비교하면 false가 나온다.
    (p1 == p2 -> 0x100 == 0x200 -> false)
  • 하지만, equals를 통해 오버라이딩 해서 값을 비교하면 true가 나온다.
    (p1.equals(p2) -> this.id == ((Person)obj).id -> 8011081111222L == 8011081111222L -> true)
  • 형변환((Person)obj).id)을 하는 이유는, Object에서 id를 사용할 수 없기 때문이다.
profile
한 걸음 한 걸음 나아가는 개발자

0개의 댓글