ETC Flashcards
List
List 인터페이스를 직접 @Override를 통해 사용자가 정의하여 사용할 수도 있으며, 대표적인 구현체로는 ArrayList가 존재한다. 이는 기존에 있었던 Vector를 개선한 것이다. 이외에도 LinkedList 등의 구현체가 있다.
Map
대표적인 구현체로 HashMap이 존재한다. (밑에서 살펴볼 멀티스레드 환경에서의 개발 부분에서 HashTable 과의 차이점에 대해 살펴본다.) key-value 의 구조로 이루어져 있으며 Map 에 대한 구체적인 내용은 DataStructure 부분의 hashtable 과 일치한다. key 를 기준으로 중복된 값을 저장하지 않으며 순서를 보장하지 않는다. key 에 대해서 순서를 보장하기 위해서는 LinkedHashMap을 사용한다.
Set
대표적인 구현체로 HashSet이 존재한다. value에 대해서 중복된 값을 저장하지 않는다. 사실 Set 자료구조는 Map 의 key-value 구조에서 key 대신에 value 가 들어가 value 를 key 로 하는 자료구조일 뿐이다. 마찬가지로 순서를 보장하지 않으며 순서를 보장해주기 위해서는 LinkedHashSet을 사용한다.
Stack 과 Queue
Stack 객체는 직접 new 키워드로 사용할 수 있으며, Queue 인터페이스는 JDK 1.5 부터 LinkedList에 new 키워드를 적용하여 사용할 수 있다. 자세한 부분은 DataStructure 부분의 설명을 참고하면 된다.
Annotation
어노테이션이란 본래 주석이란 뜻으로, 인터페이스를 기반으로 한 문법이다.
주석과는 그 역할이 다르지만 주석처럼 코드에 달아 클래스에 특별한 의미를 부여하거나 기능을 주입할 수 있다. 또 해석되는 시점을 정할 수도 있다.(Retention Policy) 어노테이션에는 크게 세 가지 종류가 존재한다.
JDK 에 내장되어 있는 built-in annotation과 어노테이션에 대한 정보를 나타내기 위한 어노테이션인 Meta annotation 그리고 개발자가 직접 만들어 내는 Custom Annotation이 있다.
built-in annotation 은 상속받아서 메소드를 오버라이드 할 때 나타나는 @Override 어노테이션이 그 대표적인 예이다. 어노테이션의 동작 대상을 결정하는 Meta-Annotation 에도 여러 가지가 존재한다.
Generic
제네릭은 자바에서 안정성을 맡고 있다고 할 수 있다.
다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에서 사용하는 것으로, 컴파일 과정에서 타입체크를 해주는 기능이다.
객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안전성을 높이고 형변환의 번거로움을 줄여준다.
자연스럽게 코드도 더 간결해진다. 예를 들면, Collection 에 특정 객체만 추가될 수 있도록, 또는 특정한 클래스의 특징을 갖고 있는 경우에만 추가될 수 있도록 하는 것이 제네릭이다.
이로 인한 장점은 collection 내부에서 들어온 값이 내가 원하는 값인지 별도의 로직처리를 구현할 필요가 없어진다. 또한 api 를 설계하는데 있어서 보다 명확한 의사전달이 가능해진다.
//제네릭 클래스
public class Box { // T는 타입을 의미한다.
private T data;
public void set(T data) {
this.data = data;
}
public T get() {
return data;
}
}
final
final은 해당 entity가 오로지 한 번 할당될 수 있음을 의미합니다.
final class
다른 클래스에서 상속하지 못한다.
final method
다른 메소드에서 오버라이딩하지 못한다.
final variable
변하지 않는 상수값이 되어 새로 할당할 수 없는 변수가 된다.
추가적으로 혼동할 수 있는 두 가지를 추가해봤다.
finally
try-catch or try-catch-resource 구문을 사용할 때, 정상적으로 작업을 한 경우와 에러가 발생했을 경우를 포함하여 마무리 해줘야하는 작업이 존재하는 경우에 해당하는 코드를 작성해주는 코드 블록이다.
finalize()
keyword 도 아니고 code block 도 아닌 메소드이다. GC에 의해 호출되는 함수로 절대 호출해서는 안 되는 함수이다. Object 클래스에 정의되어 있으며 GC 가 발생하는 시점이 불분명하기 때문에 해당 메소드가 실행된다는 보장이 없다. 또한 finalize() 메소드가 오버라이딩 되어 있으면 GC 가 이루어질 때 바로 Garbage Collecting 되지 않는다. GC 가 지연되면서 OOME(Out of Memory Exception)이 발생할 수 있다.
Overriding vs Overloading
오버라이딩(Overriding)
상위 클래스에 존재하는 메소드를 하위 클래스에서 필요에 맞게 재정의하는 것을 의미한다.
오버로딩(Overloading) 상위 클래스의 메소드와 이름, return 값은 동일하지만, 매개변수만 다른 메소드를 만드는 것을 의미한다. 다양한 상황에서 메소드가 호출될 수 있도록 한다.
Access Modifier
public
어떤 클래스에서라도 접근이 가능하다.
protected
클래스가 정의되어 있는 해당 패키지 내 그리고 해당 클래스를 상속받은 외부 패키지의 클래스에서 접근이 가능하다.
(default)
클래스가 정의되어 있는 해당 패키지 내에서만 접근이 가능하도록 접근 범위를 제한한다.
private
정의된 해당 클래스에서만 접근이 가능하도록 접근 범위를 제한한다.
Wrapper class
기본 자료형(Primitive data type)에 대한 클래스 표현을 Wrapper class 라고 한다.
Integer, Float, Boolean 등이 Wrapper class 의 예이다. int 를 Integer 라는 객체로 감싸서 저장해야 하는 이유가 있을까? 일단 컬렉션에서 제네릭을 사용하기 위해서는 Wrapper class 를 사용해줘야 한다.
또한 null 값을 반환해야만 하는 경우에는 return type 을 Wrapper class 로 지정하여 null을 반환하도록 할 수 있다. 하지만 이러한 상황을 제외하고 일반적인 상황에서 Wrapper class 를 사용해야 하는 이유는 객체지향적인 프로그래밍을 위한 프로그래밍이 아니고서야 없다.
일단 해당 값을 비교할 때, Primitive data type 인 경우에는 ==로 바로 비교해줄 수 있다. 하지만 Wrapper class 인 경우에는 .intValue() 메소드를 통해 해당 Wrapper class 의 값을 가져와 비교해줘야 한다.
AutoBoxing
JDK 1.5 부터는 AutoBoxing과 AutoUnBoxing을 제공한다. 이 기능은 각 Wrapper class 에 상응하는 Primitive data type 일 경우에만 가능하다.
List lists = new ArrayList<>();
lists.add(1);
우린 Integer라는 Wrapper class 로 설정한 collection 에 데이터를 add 할 때 Integer 객체로 감싸서 넣지 않는다. 자바 내부에서 AutoBoxing해주기 때문이다.