
자바의 신 : VOL.1 기초 문법편 3판 총정리, Chapter 14 ~ 17Java 의 Exception Handling Java 의 예외처리는 try, catch, finally 키워드를 이용해 진행할 수 있다. 이는 Python 의 try-except-finally 와 거의 동등하다.
Java 의 예외는 크게 3 종류로 나뉘는데, Error, Runtime Exception, Checked Exception 이다. 각각에 대한 설명은 다음과 같다.
Error : 대부분 개발자가 처리할 수 없는 하드웨어 에러 또는 프로그램 외적인 이유로 인해 발생한다. java.lang.VirtualMachineError, java.io.IOError 같은 예외가 있다.
Runtime Exception : Runtime Exception 은 (특성만으로 따지면) Error 가 아니면서, 예외처리를 하지 않아도 compile error 가 발생하지 않는 예외이다. Runtime Exception 은 프로그램 내적인 이유로 발생하며, java.lang.NullPointerException, java.nio.file.FileSystemNotFoundException 그리고 java.lang.RuntimeException 등 같은 예외가 있다.
Checked Exception : Checked Exception 은 try-catch 또는 throws 키워드로 예외처리를 하지 않을 시, compile error 를 일으키는 예외를 말한다. Checked Exception 은 사실 Error, Runtime Exception 을 제외한 모든 예외들이며, 예외 클래스의 부모인 Exception, Throwable 또한 Checked Exception 이다.
Java 의 예외 구조 Java 는 객체지향 언어이므로Java 의 예외들 또한 상속 관계가 존재한다. 이 중 Runtime Exception, Chekced Exception 은 java.lang.Exception 의 자식들이며, java.lang.Exception 과 Error 는 java.lang.Throwable 의 자식들이다.
Throwable 의 메서드 java.lang.Throwable 은 모든 예외의 자식이다. Throwable 클래스에 정의된 메서드 중 교재에 설명된 메서드는 다음과 같다.
Method | Description |
|---|---|
String getMessage() | 현 객체에 저장된 에러 메시지를 반환한다. |
String toString() | 현 객체의 class 와 저장된 에러 메시지를 포함하는 String 을 반환한다. |
void printStackTrace() | 에러 스트림 에 toString() 메서드와 예외가 발생하기 까지의 호출 관계 (stack trace) 를 출력한다. |
throws Java 의 메서드는 throws 키워드를 이용해, 메서드가 호출된 곳으로 예외를 반환시킬 수 있다.
String 클래스의 구현 Java 의 소스를 까보면 String 클래스는 다음처럼 선언되어 있다.
public final class String
extends Object
implements Serializable, Comparable<String>, CharSequence, Constable, ConstantDesc
교재에서 이 중 Serializable, Comparable, CharSequence 에 대해 설명하고 있다. 이들을 정리하면 다음과 같다.
Serializable : 객체를 직렬화 할 때 사용되는 interface. 안에 선언된 추상 메서드가 한개도 없다.Comparable : int compareTo 라는 추상 메서드를 위한 interface. compareTo 메서드는 매개변수로 주어진 객체와 현재 객체의 순서 를 비교할 때 사용된다.CharSequence : 구현하는 클래스가 문자열을 다루기 위한 클래스라는 것을 명시.Character Set 캐릭터 셋 이란 글자의 표현을 위한 mapping 방식 으로, 쉽게 말해 글자에 대한 인코딩 방식들의 집합 이라 할 수 있다.
Oracle Docs 에 의하면 "Java 플랫폼이면 반드시 구현해야 할 캐릭터 셋" 이 존재하며, 이를 나타내면 다음과 같다.
캐릭터 셋 이름 | 설명 |
|---|---|
US-ASCII | 7 비트 아스키 |
ISO-8859-1 | ISO (International Organization for Standardization) 라틴 알파벳 |
UTF-8 | 8 비트 UCS 변환 포맷 |
UTF-16BE | 16 비트 big-endian UCS 변환 포맷 |
UTF-16LE | 16 비트 little-endian UCS 변환 포맷 |
UTF-16 | 16 비트 UCS 변환 포맷. endian 은 byte-order mark 라는 것에 의해 정해진다. |
String 클래스에는 byte 배열을 캐릭터 셋 으로 decoding 해 문자열로 만드는 생성자가 다수 존재한다.
String 클래스의 메서드intern() 메서드 String 클래스에는 intern() 메서드가 있다. Java 의 문자열은 모두 heap 메모리에 저장된다. (JDK 7 부터 heap 으로 저장)
이 중 Literal String 은 String Constant Pool 에 따로 저장되는데, Java 는 같은 값을 가진 리터럴 문자열이 String Pool 에 존재하는지 확인하고, 만약 존재한다면 그 문자열을 참조해 재사용 한다.
intern() 메서드는 어느 문자열을 String Pool 에 넣고 이를 반환하는 메서드이다. 때문에 intern() 메서드를 남발하면 메모리가 부족해질 수 있다.
String 은 immutable Java 에서 어느 객체가 생성된 후, 그 객체의 상태 가 변할 수 없다면, 이를 "불변 객체" (immutable object) 라 부른다.
Java 의 immutable object 에는 대개 primitive data types 의 wrapper class 가 속하고, 그 외에 여러것이 속한다.
String 클래스 또한 immutable 한데, 이를 보완하기 위해 StringBuffer, StringBuilder 를 사용한다.
두 클래스가 제공하는 메서드는 동일하다. 다만 StringBuffer 는 Thread safe 하고, StringBuilder 는 그렇지 않다는 특징이 있다.
Nested Class Java 에도 클래스 안에 클래스를 선언할 수 있다. 이러한 클래스를 Nested Class 라 부른다.
Nested Class 선언 방식에 따라 Static Nested Class, Inner Class 로 나눌 수 있다. Inner Class 는 말 그대로 클래스 속에 정의된 클래스이고, Static Nested Class 는 이를 정적으로 정의한 클래스이다.
Nested Class 형태를 사용하는 가장 큰 이유는 코드를 간단히 표현하기 위함이다.
(Static Nested Class)(Inner Class)Static Nested Class 의 특징 Static Nested Class 는 static 키워드를 이용해 정의한 Inner Class 이다.
Inner Class 의 특징상, Inner Class 객체는 항상 Outter Class 를 참조한다. 때문에 Inner Class 객체가 reachable 한 이상, Outter Class 는 GC 에 의해 수거되상이 되지 않는다.
반면 Static Nested Class 는 객체에 의한 참조 가 아닌, 클래스에 의한 참조 이기 때문에, 위오 같은 상황이 일어나지 않는다. (Outter Class 가 GC 에 수거될 수 있다)
더불어 Static Nested Class 는 클래스간 static 한 참조 를 가질 뿐, Static Nested Class 객체가 정적이지 않다는 점에 유의해야 한다.
익명 클래스 와 익명 내부 클래스 익명 클래스 란 interface, 추상 클래스 등을 클래스 선언 없이 확장 (extends) 하거나 구현 (implements) 한 클래스이다.
또한 익명 내부 클래스 는 위 interface, 추상 클래스 등이 Inner Class 로 바뀐 것일 뿐이다.
이들을 잘 이용하면 더 간결한 코드를 얻을 수 있다.
Nested Class 의 접근 가능 범위 간단히 말하자면, Static Nested Class 는 Inner static field <--> Outter static field 로 만 참조 가능하고,
Inner Class 는 Inner field <-->>> Outter field 이다.
Static Nested Class 는 static field 들만 접근 가능하다는 뜻이고, Inner Class 는 Outter Class 의 모든 field 를 접근 가능한 반면, Outter Class 에서 Inner Class field 는 상당히 제한된다는 뜻이다.
annotation Java 에는 annotation 이 존재한다. annotation 은 Java 소스 코드에 추가하여 사용할 수 있는 메타데이터의 일종으로, 다음과 같은 용도로 사용될 수 있다.
compiler 에게 어느 정보를 알려주기 위해compile 할 때나 설치 (deployment) 시의 작업을 지정하기 위해Java 에 미리 정해진 annotation 은 현재 총 11 개가 있으며, 이를 용도별로 나타내면 다음과 같다.
Java 언어에 사용되는 annotation
@Override, @Deprecated, @SuppressWarnings, @SafeVarargs, @FunctionalInterface, @Nativeannotation 을 위한 meta annotation
@Target, @Retention, @Documented, @Inherited, @Repeatable Java 언어에 사용되는 annotationannotation 을 위한 meta annotationannotation 선언 annotation 은 @interface 키워드를 이용해 직접 만들 수 있다.
annotation 에는 annotation 메서드 원소 를 지정할 수 있으며, Reflection API 를 이용해 사용된 annotation 의 원소 값을 직접 확인해 볼 수도 있다.