메모리 상수풀 영역
- JVM의 메모리 영역 중 힙 영역안에 있으며 리터럴과 같은 상수들이 저장되는 곳이다. 프로세스가 종료될때까지 지워지지 않으며 상수가 필요할때 가장 먼저 이곳에서 찾는다.
JDBC
- 자바에서 데이터베이스를 사용하기 위해 필요한 API로 해당 DB를 사용할 수 있는 방법 제공
리플렉션
- 정상적으로 컴파일러를 거치지 않고 런타임에 메모리 상의 객체에 바로 접근할 수 있는 자바 API이다.
해당 객체가 가진 메소드, 생성자, 필드에 대한 정보를 조작할 수 있다.
제네릭
- 제네릭을 사용하면 해당 클래스의 타입이 컴파일 이전이 아닌 런타임때 결정된다. C++템플릿과 비슷한 개념인것 같다. 기존 C++ 템플릿에선 컴파일때 인스턴스된 객체의 코드가 새로 생성되어 컴파일되었다. 그러면 과연 자바에선 이러한 제네릭이 어떤 과정으로 타입변환이 이뤄지는지 궁금해서 찾아보았다.
Test.java
class Test {
public static void main(String[] args) {
GenericArrayList<Integer> intList = new GenericArrayList<>();
intList.add(1);
intList.add(2);
int intValue1 = intList.get(0); // 형변환이 필요없다
int intValue2 = intList.get(1); // 형변환이 필요없다
// String strValue = intList.get(0); // 컴파일에러
}
}
디컴파일 한 결과 (Test.java -> Test.class -> decompile)
class Test {
Test() {
}
public static void main(String[] var0) {
GenericArrayList var1 = new GenericArrayList(); // 제네릭이 사라졌다
var1.add(1);
var1.add(2);
int var2 = (Integer)var1.get(0); // 형변환이 추가되었다
int var3 = (Integer)var1.get(1); // 형변환이 추가되었다
}
}
출처 - https://yaboong.github.io/java/2019/01/19/java-generics-1/
해당 블로그에서 본 바와 같이 먼저 제네릭은 컴파일 시간때가 아닌 런타임때 결정나며 디컴파일 결과 제네릭 적용안된 데이터를 제네릭된 타입에 맞춰 형변환 시켜줌을 알수있었다.
또한 static 변수의 경우 실행 초기에 값으로 공유 되기에 타입추론이 무조건 되야한다. 하지만 static 메서드의 경우는 제네릭을 허용하는데, 그 이유는 static 변수와 달리 값이 아닌 메서드의 틀만 공유되기 때문이라고 한다.
또한 제네릭 타입을 한정시킬수 있다.
//Number클래스를 상속한 타입만 가능
public class GenericArrayList<T extends Number>
//Number클래스가 상속한 타입만 가능
public class GenericArrayList<T super Number>
제네릭과 템플릿 둘다 사용자 입장에서 코드의 중복을 줄여준단 점이 가장 큰것 같다.
'언어 > Java' 카테고리의 다른 글
(Java)JVM / JRE / JDK / 컴파일 동작 과정 (0) | 2021.07.23 |
---|---|
(Java)OOP / 인터페이스와 추상클래스 (0) | 2021.07.23 |