JVM이란?
Java Virtual Machine의 약자로, 자바 바이트 코드를 실행할 수 잇는 주체
이다.
자바 바이트 코드
운영체제에 독립적이며 모든 JVM 구격에 정의된 대로 자바 바이트 코드를 실행한다.
자바 바이트 코드의 확장자는 .class 입니다.
JVM의 구조와 동작
JAVA 소스 코드 파일 -> 컴파일러 -> 자바 바이트 코드 파일 -> 클래스 로더 -> JVM RUNTIME DATA AREA -> Interpreter or JIT Compiler
Method Area
class의 정보 (클래스 이름, 부모 클래스 이름, 메소드, 변수)를 저장한다. Method Area에 접근하기 위한 방법으로는 Java Reflection이 있다고 할 수 있다.
Java Reflection이란?
런타임
에 클래스와 인터페이스 등을 검사하고 조작할 수 있는 기능을 뜻한다.
좀 더 풀어서 설명하자면,
프로그램 실행 중
에 사용자와
운영체제 및 기타 프로그램과 상호작용
하면서 클래스와 인터페이스 등을 검사하고 조작할 수 있는 기능이다.
좀 더 자세히 설명하자면, Runtime에 Method Area에 로딩된 클래스들의 메타데이터를 통해 클래스의 정보를 분석하고, 객체를 생성하고, 생성된 객체를 통해 메소드를 호출하고, 필드에 접근하는 등의 기능
을 말한다.
Reflection 사용법
Method Area를 사용하기 위해서 Class
Type을 사용해줄 수 있다.
public class ClassExample {
public static void main(String[] args) throws ClassNotFoundException {
final Class<MyClass> class1 = MyClass.class;
final MyClass obj = new MyClass();
final Class<? extends MyClass> class2 = obj.getClass();
final Class<?> class3 = Class.forName("MyClass");
}
}
class MyClass { }
Class
Type에서
- getDeclaredField()를 통해서 Field 값을 추출 해낸다.
- get( Class Instance )를 통해서 value에 접근할 수 있는데 지금 위의 상황에선 에러가 발생한다.
- MyClass의 name Filed가 private이기 때문
public class ClassExample {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
final Class<MyClass> class1 = MyClass.class;
// NoSuchFieldException 발생 가능
final Field declaredField = class1.getDeclaredField("name");
declaredField.setAccessible(true);
final MyClass myClass = new MyClass();
// IllegalAccesssException 발생 가능
final String name = (String) declaredField.get(myClass);
System.out.println(name);
}
}
class MyClass {
private final String name = "헐크";
}
- 이 때 위와 같이 declaredField에 setAccessible(true)를 설정해주면 값에 접근할 수 있다.
Reflection 사용용도
리플렉션 API의 대표적인 사용 예시로 스프링 프레임워크가 있다. 스프링의 IoC 컨테이너에서 빈(Bean) 객체를 생성하고, 의존성 주입(Dependency Injection)을 처리하는 데 사용된다. 런타임 시에 동적으로 클래스를 로딩하고 객체를 생성하여 의존성을 주입하는 방식을 사용된다.
또한, 자바 직렬화(Serialization)에서도 리플렉션 API가 사용된다. 직렬화란 객체를 바이트 스트림으로 변환하여 저장하거나 네트워크를 통해 전송할 수 있는 방법입니다. 이 때, 리플렉션 API를 사용하여 객체의 정보를 분석하고 바이트 스트림으로 변환하는 작업을 수행한다.
Reflection 사용시 단점
Reference
https://velog.io/@dyunge_100/JAVA-JVM%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0-%EB%B0%8F-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC (opens in a new tab)
https://sh970901.tistory.com/120 (opens in a new tab)
우테코 헙크의 자바 (opens in a new tab)