java.lang.Class
- 클래스에 대한 메타데이터 관리
- 어노테이션
- 클래스 생성자
- 클래스 필드
- 클래스 메서드
- 부모 클래스, 구현 인터페이스 조회
클레스 데이터 - JVM 메모리 > 메소드 영역 인스턴스 정보 - JVM 메모리 > 힙 영역
- public 생성자 없음
- JVM에 의해 자동 생성됨
- 다음 방법으로 인스턴스를 가져올 수 있음
Class<?> c = MyCsStudy.class;
Class<?> c = myCsStudy.getClass();
Class<?> c = Class.forName("org.....MyCsStudy");
.getMethods : 상속한 메서드를 포함, 모든 public 메서드 가져옴 .getDeclaredMethods : 직접 클래스에서 선언한 모든(pub,pri,protected 모두) 메서드 가져옴
Class<?> classInstanceOfClassClass = Class.class;
System.out.println("classInstanceOfClassClass.getDeclaredMethods() = "
+ Arrays.toString(classInstanceOfClassClass.getDeclaredMethods()));
classInstanceOfClassClass.getDeclaredMethods() =
[
public java.lang.String java.lang.Class.getName(),
private void java.lang.Class.checkPackageAccess(java.lang.SecurityManager,java.lang.ClassLoader,boolean),
public static java.lang.Class java.lang.Class.forName(java.lang.String,boolean,java.lang.ClassLoader) throws java.lang.ClassNotFoundException,
public static java.lang.Class java.lang.Class.forName(java.lang.String) throws java.lang.ClassNotFoundException,
public static java.lang.Class java.lang.Class.forName(java.lang.Module,java.lang.String),
private static native java.lang.Class java.lang.Class.forName0(java.lang.String,boolean,java.lang.ClassLoader,java.lang.Class) throws java.lang.ClassNotFoundException,
public java.lang.String java.lang.Class.toString(),
public java.lang.Module java.lang.Class.getModule(),
public java.security.ProtectionDomain java.lang.Class.getProtectionDomain(),
public native boolean java.lang.Class.isAssignableFrom(java.lang.Class),
public native boolean java.lang.Class.isInstance(java.lang.Object),
public native int java.lang.Class.getModifiers(),
// ...
]
- Class 객체 -> Constructor 객체 ->
.newInstance()
.getDeclaredConstructors();, .getConstructors();, .getDeclaredConstructor();, .getConstructor();
- private 생성자인 경우,
constructor.setAccessible(true);
설정하여 접근 가능
Constructor<?> publicConstructor = child.getDeclaredConstructor();
// privateConstructor.setAccessible(true);
publicConstructor.newInstance();
- Field객체를 통해 접근 가능 (
.getDeclaredFields();, .getFields();, .getDeclaredField();, .getField();
) - private 필드인 경우,
.setAccessible(true);
설정하여 접근 .get(...)
,.set(...)
-> 조회/수정
Field[] fields = child.getDeclaredFields();
Field field = child.getField("value");
- Method 객체를 통해 접근 가능 (
.getDeclaredMethods();, .getMethods();, .getDeclaredMethod();, .getMethod();
) - private 필드인 경우,
.setAccessible(true);
설정하여 접근 .invoke(...)
-> 실행
.getDeclaredAnnotations(), .getDeclaredAnnotations()
- 어노테이션이 붙어있는지 확인 후 로직 수행
- 컴파일 시점까지 클래스,객체의 정보를 알 수 없는 경우
- 프레임워크
- 라이브러리
- 어노테이션
- 일반 메서드 호출보다 성능이 떨어짐
컴파일 시점이 아니라 런타임 시점에서 클래스를 분석하기 때문
JVM 최적화 불가 - 컴파일 시점에서 타입 체크 기능을 사용할 수 없다.
- 코드가 지저분하고 장황해짐
- 런타임 에러가 매우 많이 발생한다.
- 내부 노출, 추상화가 파괴됨, 불변성 보장 x
- 런타임에 존재하지 않을 수도 있는 클래스,메서드,필드와의 의존성 관리
- 버전이 여러 개 있는 외부 패키지
가장 오래된 버전으로 컴파일 -> 이후 버전의 클래스는 리플렉션으로 접근 - 등등, 꼭 필요할때만 쓰자
- (이펙티브 자바 ch.65 참고)