본문 바로가기
Java

[Java] 현재 실행중인 클래스명, 메소드명 알아내기

by doogfoot 2022. 12. 29.

[Java] 현재 실행중인 클래스명, 메소드명 알아내기

 

로깅 같은 기능을 개발하다 보면 현재 클래스명과 메소드명을 로그로 출력해야 되는 경우가 있습니다.

 

이때 문자열로 클래스명, 메소드명을 수동으로 입력하다 보면 실수나 오타가 발생할 수 있기 때문에 자동으로 알아낼 수 있다면 좋겠다고 생각했습니다.

 

방법은 여러가지 있을것 같은데 크게 두가지 방법을 설명드리겠습니다.


첫번째는 java의 리플렉션 기능을 이용하여 알아내는 방법입니다.

public String exampleMethod() {
    String className = new Object(){}.getClass().getEnclosingClass().getSimpleName();
    String methodName = new Object(){}.getClass().getEnclosingMethod().getName();
}

 

새로운 Object 인스턴스를 만들고 그 클래스 정보를 getClass를 통해 가져올수 있습니다 (리플렉션)

 

Object 클래스에서 getEnclosingClass 함수를 통해 해당 클래스를 둘러싸고 있는 클래스 정보를 가져올 수 있습니다.

 

Object 클래스를 둘러싸고 있다는 것이 의미하는건 new Object() 호출한 exampleMethod의 클래스를 의미합니다. (즉, 우리가 알아야하는 클래스명, 메소드명을 가지고 있는 클래스)

 

다만 리플렉션은 성능에 오버헤드가 있기 때문에 개인적으로 로깅할 때 사용하는 것은 좋지 않다고 생각합니다


두번째 방법은 현재 실행중인 쓰레드의 StackTrace 에서 얻는 방법입니다.

String className = Thread.currentThread().getStackTrace()[1].getClassName();
String methodName =  Thread.currentThread().getStackTrace()[1].getMethodName();

 

리플렉션보다 좋은 방법이라고 생각되지만 StackTrace 배열의 두번째 요소(index:1)에서만 클래스와 메소드 정보를 가져오는데 그 이유를 정확히 알고 써야 될 것 같습니다.

 

StackTrace 는 trace 를 stack에 담고 있다는 의미이며, 쉽게 말해 지금까지 호출된 클래스와 메소드 정보를 순서대로 스택에 담고 있었습니다. 

 

직접 디버깅해보면 알겠지만 stacktrace 배열에 가장 첫번째 요소는 Thread클래스의 getStackTrace() 메소드정보가 들어있습니다.

 

두번째 요소에는 우리가 위에서 getStackTrace()를 호출한 클래스 및 메소드 정보가 들어있습니다.

 

정리하면 우리가 실행중인 현재 클래스와 메소드 정보를 얻기위해서는 StactTrace의 두번째 요소를 가져오면 된다는 것을 알 수 있습니다.

 

한 단계 더 생각해보면 메소드명을 얻을 수 있는 유틸 클래스를 하나 만들고, 메소드명을 알기 원하는곳에서 이 유틸 클래스를 호출해서 사용할 경우는 몇번째 배열을 가져와야 할까요??

public class UtilClass {
	public static String getCurrentMethodName() {		
		return Thread.currentThread().getStackTrace()[2].getMethodName();
	}
}

public class CurrentClass {
	public String request() {		
		String methodName = UtilClass.getCurrentMethodName();
	}
}

 

정답은 위에 코드에서처럼 세번째 요소(index:2)를 가져오는 방식으로 유틸클래스를 만들면 됩니다

 

만약 처음 소개한대로 두번째 요소에서 가져오는 방식을 그대로 썼다면 methodName변수에는 "getCurrentMethodName" 이라는 문자열이 들어가서 우리가 원하는 대로 동작하지 않게 됩니다.

 

현재 쓰레드 스택에서 정보를 가져오는 방식은 하나의 쓰레드에서 함수를 순차적으로 호출할 경우에만 정상 동작할 것 같습니다.

 

만약 호출하는 함수와 호출당하는 함수가 각각 다른 쓰레드에서 실행되는 경우 StackTrace는 어떻게 될지 궁금했습니다. 

 

원하는대로 동작하지 않을 것 같은데 주제와 점점 멀어지고 있어서 다음에 정리하도록 하겠습니다

 

댓글