Java 클래스 정보 알아내기

📌 reflection 패키지

reflection 패키지를 활용하면 JVM에 로딩된 클래스와 메서드 정보를 알 수 있다.

Class 클래스

클래스 객체를 만드는 경우 Object 클래스의 getClass() 메서드를 사용하는 것이 일반적이다. 해당 클래스는 클래스에 대한 정보를 얻을 수 있다. 해당 클래스의 주요 메서드는 아래와 같다.

클래스 정보

String getName() : 클래스 이름을 반환한다. (패키지 정보가 포함되어 있다)
Package getPackage() : 클래스 패키지 정보를 담아 반환한다.
int getModifiers() : 클래스의 접근자 정보를 int로 반환한다.
String toString() : 해당 클래스의 객체를 문자열로 반환한다.

클래스에 선언된 변수 정보

Field[] getFields() : public으로 선언된 변수 목록을 배열에 담아 반환한다.
Field getField(String name) : public으로 선언된 name과 동일한 이름의 변수를 반환한다.
Field[] getDeclaredFields() : 변수 목록을 배열에 담아 반환한다. (private 포함)
Field getDeclaredField(String name) : name과 동일한 이름의 변수를 반환한다. (private 포함)

클래스의 생성자 정보

Constructor[] getConstructors() : 해당 클래스의 public 생성자 정보 목록을 배열에 담아 반환한다.
Constructor[] getDeclaredConstructors() : 해당 클래스의 모든 생성자 정보 목록을 배열에 담아 반환한다. (private 포함)

클래스의 메서드 정보

Method[] getMethods() : public으로 선언된 메서드 목록을 배열에 담아 반환한다. (상속받은 메서드 포함)
Method getMethod(String name, Class... parameterTypes) : 메서드 이름과 매개 변수 타입에 맞는 public 메서드를 반환한다.
Method[] getDeclaredMethods() : 해당 클래스의 모든 메서드 정보 목록을 배열에 담아 반환한다. (private 포함)
Method getDeclaredMethod(String name, Class... parameterTypes) : 메서드 이름과 매개 변수 타입에 맞는 메서드를 반환한다. (private 포함)

사용 예시 (클래스 이름 가져오기)

String className = this.getClass().getName();
Java

Method 클래스

해당 클래스는 메서드에 대한 정보를 알 수 있다. 그러나 Method 클래스는 생성할 수 없다. (생성자가 없음) 따라서 Class 클래스에서 메서드 정보를 알 수 있는 메서드를 호출해야 한다. Method 클래스의 주요 메서드는 아래와 같다.
String getName() : 해당 메서드의 이름을 반환한다.
int getModifiers() : 해당 메서드의 접근자 정보를 반환한다.
Class<?> getReturnType() : 해당 메서드의 리턴 타입을 반환한다.
Class<?> getParameterTypes() : 해당 메서드의 매개변수의 타입 목록을 배열에 담아 반환한다.
Class<?> getDeclaringClass() : 해당 메서드가 선언된 곳의 Class 클래스를 반환한다.
Class<?>[] getExceptionTypes() : 해당 메서드에 정의된 예외 타입 목록을 배열에 담아 반환한다.
Object invoke(Object obj, Object... args) : 해당 메서드를 실행한다.
String toGenericString() : 타입 매개변수를 포함한 해당 메서드의 정보를 문자열로 반환한다.
String toString() : 메서드 정보를 문자열로 반환한다.

Field 클래스

클래스에 있는 변수들의 정보를 알 수 있다. 그러나 해당 클래스는 생성할 수 없다. (생성자가 없음) 따라서 Class 클래스의 변수 정보를 알 수 있는 메서드를 호출해야 한다. Field 클래스의 주요 메서드는 아래와 같다.
int getModifiers() : 해당 변수의 접근자 정보를 반환한다.
String getName() : 해당 변수의 이름을 반환한다.
String toString() : 해당 변수의 정보를 반환한다.

📌 이런식으로 활용하지 말자.

클래스 이름 확인하는 경우

타입을 직접 확인하는 것을 권장하지는 않지만, 확인해야 하는 상황이 생긴다면, reflection을 이용하는 것보다 instanceof 키워드를 사용하는 것이 더 낫다. 성능이 약 6배 더 빠르다.

잘못된 방식

if (obj.getClass().getName().equals("java.math.Integer") { ... }
Java

개선 후

if (obj instanceof Integer) { ... }
Java

Class 클래스를 많이 사용하는 경우

클래스에 대한 메타 정보는 JVM의 Perm 영역에 저장된다. Class 클래스를 많이 사용하게 되면, Perm 영역이 더 이상 사용할 수 없어 OutOfMemoryError가 발생할 수 있기 때문에 조심해서 사용해야 한다.

📌 참고 자료

TOP