31. 예외처리
(1) 컴파일 에러 : 컴파일 시에 발생하는 에러
(2) 런타임 에러 : 실행 시에 발생하는 에러
(2.1)에러(error) : 프로그램 코드에 의해서 수습될 수 없는 오류
(2.2)예외(exception) : 프로그램 코드에 의해서 수습될 수 있는 오류
(2.2.1)Exception과 그 자손들(checked예외)
- 예외 필수처리(try-catch), 클래스 이름에 선언
- 사용자의 실수와 같은 외적인 요인에 의해 발생
IOexception (입출력이 잘못되었을 때) |
ClassNotFoundException(클래스의 이름을 잘못적었을 때) |
FileNotFoundException(존재하지 않는 파일의 이름을 입력했을 때) |
DataFormatException(데이터 형식이 잘못됐을 때) |
(2.2.2)RuntimeException과 그 자손들(unchecked예외)
- 예외 선택처리, 클래스 이름에서 선언하지 않음
- 프로그래머의 실수로 발생하는 예외
ArrayIndexOutOfBoundsException(배열의 범위를 벗어남) |
NullPointerException(값이 Null인 참조변수의 멤버를 호출) |
ClassCastException(클래스간의 잘못된 형변환) |
ArithmeticException(정수를 0으로 나누려고 했을 때) |
(3) 논리적 에러 : 실행은 되지만, 의도와 다르게 동작하는 것
32. 예외처리(exception handling)
- 예외의 경우 프로그래머가 이에 대한 처리를 미리 해주어야 한다.
정의 : 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비해 코드를 작성
목적 : 프로그램의 비정상 종료를 방지하고 정상적인 실행상태를 유지하는 것
*예외를 처리하지 못할 경우 프로그램은 비정상적으로 종료되며 이러한 예외는
JVM의 ‘예외처리기’가 받아서 예외의 원인을 화면에 출력한다.
*예외를 처리하기 위해 try-catch문 사용
try { // 예외가 발생할 가능성이 있는 문장들 삽입 } catch (Exception e1) { // Exception1이 발생했을 경우, 이를 처리하기 위한 문장 삽입 ] catch (Exception e2) { // Exception2가 발생했을 경우, 이를 처리하기 위한 문장 삽입 } finally { // 예외의 발생여부와 관계없이 항상 수행되어야 하는 문장 삽입 } |
1) 하나 이상의 catch블럭이 올 수 있으며, 발생한 예외의 종류와 일치하는
단 한개의 catch블럭만이 수행된다.
2) if문과 달리, try블럭이나 catch블럭 내에 포함된 문장은 괄호를 생략 불가
3) n개 이상의 catch블럭 생성시 조상클래스의 예외 참조변수를 하단으로
배치한다.
32-1. 멀티 catch블럭
- 여러 catch블럭을 ‘|’기호를 사용해 하나의 catch블럭으로 합치는 것
- 연결할 수 있는 예외 클래스의 개수에는 제한이 없다.
- 이때, |로 연결된 클래스가 조상과 자손 관계에 있다면 컴파일 에러가
발생하므로 불가하다.
- 멀티catch블럭은 참조변수로 두 클래스간의 공통된 메서드만 호출 가능
- try-catch블럭으로 처리되지 못한 예외는 종료된다.
32-2. 예외 인스턴스 발생
[1] 예외 발생시 catch블럭의 괄호에 선언된 참조변수를 통해 예외 인스턴스에
접근할 수 있다.
[2] printStackTrace() : 예외발생 당시의 호출스택에 있었던 메서드의 정보와
예외메시지를 화면에 출력한다.
[3] getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻는다.
32-3. 예외 발생시키기
- 키워드 throw를 사용해 프로그래머가 고의로 예외를 발생시킨다.
[1] 연산자 new를 이요해 발생시키려는 예외 클래스의 객체 생성
Exception e = new Exception(”고의로 발생시켰음”);
[2] 키워드 throw를 이용해 예외를 발생시킨다.
throw e;
(=throw new Exception(”고의로 발생시켰음”))
32-4. 메서드에 예외 선언하기
- 메서드의 선언부에 키워드 throw를 사용해서 메서드 내에서 발생할 수 있는
예외를 적어준다.
- 예외가 여러개일 때는 쉼표로 구분한다.
* 예외를 발생시키는 키워드 : throw
* 예외를 선언하는 키워드 : throws
- 메서드에 예외를 선언해주면 체크드 예외를 try-catch문으로 처리해주지
않아도 컴파일 에러가 발생하지 않는다.
32-5. 연결된 예외(chained exception)
- 하나의 예외를 다른 예외의 원인 예외로 포함시켜 처리해주는 것
- 여러 가지 예외를 하나의 큰 분류의 예외로 묶어서 다루기 위함
- checked예외를 unchecked예외로 바꾼다.
[1] Throwable initCause(Throwable cause)
: 지정한 예외를 원인 예외로 등록
[2] Throwable getCause()
: 원인 예외를 반환
33. Object클래스
- 모든 클래스의 최고 조상이므로 모든 클래스에서 Object클래스의 멤버들을
바로 사용할 수 있다.
- 멤버변수없이 오직 11개의 메서드만 가지고 있다.
protect object clone() | 객체 자신의 복사본 반환 |
boolean equals(Object obj) | 자신과 Obj가 같은 객체인지 알려준다. (true/false로 반환) |
protected void finalize() | 거의 사용안함 |
Class getClass() | 자신의 클래스 정보를 담고 있는 Class인스턴스를 반환 |
int hashCode() | 자신의 해시코드를 반환 |
String toString() | 자신의 정보를 문자열로 반환 |
void notify() | 자신을 사용하려고 기다리는 쓰레드를 하나만 깨운다. |
void notifyAll() | 자신을 사용하려고 기다리는 모든 쓰레드를 깨운다. |
void wait() void wait(long timeout) void wait(long timeout, int nanos) |
다른 쓰레드가 notify()나 notifyAll()을 호출할 때까지 현재 쓰레드를 무한히 또는 지정된 시간동안 기다리게 한다. timeout-천 분의 1초 nanos-109분의 1초 |
[1] equals()
: 매개변수로 객체의 참조변수를 받아 비교해 결과를 boolean값으로 알려준다.
-> 따라서 서로 다른 두 객체를 해당 메서드로 비교하면 항상 false이다.
-> 객체가 가진 인스턴스값을 비교하고 싶다면 오버라이딩 해야한다.
public static void main(String[] args) { Value v1 = new Value(10); Value v2 = new Value(10); } class Value { int value; Value(int value) { this.value = value; } } |
=> v1과 v2는 서로 다른 객체이므로 equals값이 false로 반환된다. |
public static void main(String[] args) { Value v1 = new Value(10); Value v2 = new Value(10); } class Value { int value; public boolean equals(Object obj) { if(obj instanceof Value) return value ==((Value)obj).value; else return false } Value(int value) { this.value = value; } } |
=> 해당과 같이 오버라이딩 해야한다. (반환값: true) |
->String클래스는 문자열의 내용을 비교하도록 오버라이딩 되어있다.
[2] hashCode()
: 해싱기법에 사용되는 해시함수를 구현한 것으로, 해싱은 데이터관리기법 중 하나인데 다량의 데이터를 저장하고 검색하는 데 유용하다.
- 해시함수는 찾고자하는 값을 입력하면, 그 값이 저장된 위치를 알려주는 해시코드를 반환한다.
- 인스턴스 변수값으로 객체의 같고 다름을 판단하는 경우, equals메서드 뿐만 아니라 hashCode메서드도 오버라이딩해줘야 한다.
- String클래스는 문자열의 내용이 같으면 동일한 해시코드를 반환하도록 자동 오버라이딩 되어 있다.
- System.identityHashCode(Object x) : 항상 다른 해시코드값 반환
[3]toString()
: 인스턴스에 대한 정보를 문자열로 제공할 목적으로 정의한다.
-> 그러나 오버라이딩 하지 않으면 참조형의 경우 주소값이 반환되므로 인스턴스의 내용을 반환하고 싶다면 마찬가지로 오버라이딩해야 한다.
->public String toString() {}
->Object클래스에서 toString()의 접근자가 public이므로 오버라이딩을 할 때도 동일하게 public으로 한다.
[4]clone()
: 자신을 복제하여 새로운 인스턴스를 생성하는 일을 한다.
-> 원래의 인스턴스는 보존하고 clone메서드를 이용해서 새로운 인스턴스를 생성해 작업을 할 경우 작업이전의 값이 보존되므로 원래의 상태로 되돌리거나 / 변경되기 전의 값을 참고하는데 도움이 된다.
-> 참조 타입의 인스턴스 변수가 있는 경우 완전한 인스턴스 복제가 이루어지지 않으므로 clone메서드를 오버라이딩해서 사용해야 한다.
-> Cloneable 인터페이스를 구현한 클래스에서만 clone()을 호출할 수 있다.
구현을 해줄 때에는 접근 제어자를 public으로 변경해주어야 한다.
-> clone메서드는 반드시 예외처리 해주어야 한다. (CloneNotSupportedException 예외)
-> 배열의 경우 Object클래스를 상속받으며, 동시에 Cloneable인터페이스, Serializable인터페이스가 구현되어 있다. 또한, clone()이 public으로 오버라이딩 되어있고 원본과 같은 타입을 반환하므로 형변환이 따로 필요하지 않다.
=>System.arraycopy()를 통해 복사할 수도 있지만, clone()으로도 복사할 수 있다.
'Study > Java' 카테고리의 다른 글
09. <Calendar, DecialFormat, SimpleDateFormat> ~자바의 정석 summary ~ (2) | 2023.01.17 |
---|---|
08. <String클래스, 문자열-기본형 변환, 오토박싱> ~자바의 정석 summary ~ (2) | 2023.01.16 |
06. <제어자, 캡슐화, 다형성, 형변환, 인터페이스 > ~자바의 정석 summary ~ (0) | 2023.01.13 |
05. <오버로딩, 생성자, 상속, 포함 > ~자바의 정석 summary ~ (0) | 2023.01.12 |
04. <배열, 가변배열, 객체지향1 > ~자바의 정석 summary ~ (0) | 2023.01.11 |
댓글