2010-02-19 4 views
1

다른 클래스를 호출하는 클래스에 대한 정보를 얻을 수 있습니까?
클래스 호출에 대한 정보 얻기


class Bar{ 
    public Bar{} 

    public String getInvokingClassInfo(){ 
     return "..."; 
    } 
} 

class Foo{ 
    public Foo(){ 
     Bar bar = new Bar(); 
     System.out.println("Invoking class is: "+bar.getInvokingClassInfo()); 
    } 
} 

어떻게 장소에서 얻을 수 있습니다 : 클래스에 대한


System.out.println(bar.getInvokingClassInfo()); 

정보를 그 (푸에게)이 하나 (바)를 호출 :

Invoking class: Foo

답변

8
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); 
String callerClassName = stackTrace[index].getClassName(); 

이것은 점점을 현재 스레드에 대한 스택 추적. 코멘트에 언급 한 바와 같이, 구현 차이가있다, 그래서 당신은 두려워하는 경우는 다음과 같이 구현할 수 있습니다 다음 StackTraceElement 배열을

  • 루프
  • 때마다 당신을 (루프 외부에서 선언 된 카운터 변수를 사용하여) 현재 클래스 이름과 현재 메소드가 발생하면 배열의 다음 요소를 가져옵니다. 이는 호출자가됩니다.
  • 을 (즉, 위의 코드에서 의미 index 무엇을의) 경우 위의 당신은 항상 new Exception().getStackTrace()
+0

올바르지 않습니다. 배열의 최초의 요소는 getStackTrace 메서드이며, getStackTrace()에 의해 내부적으로 호출되는 다른 메서드가 될 가능성이 있습니다. 다른 버전의 Sun VM은 여기에서 다른 동작을 보여줍니다. 1.5.0_15에서는, 최초의 2 개의 요소는 Thread.dumpThreads와 Thread.getStackTrace로, 1.5.0_18에서는 최초의 요소는 Thread.getStackTrace입니다. – jarnbjo

+0

그것은 내 목적을 위해 완벽하게 작동하고 있습니다.

 public String getInvokingClassInfo(){ StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); return stackTrace[stackTrace.length-2].getClassName(); }  
저는 약간의 기분이 좋지만 디버깅에 대해서는 괜찮습니다. – kospiotr

+0

예, 업데이트되었습니다. 이 결과 색인 만 증가합니다. – Bozho

3

로 다시 떨어질 수 관련 정보를 제공하지 않습니다 내가 생각할 수있는 솔루션 것 (일그러 추한하지만) 가장 Bar 안에 예외를 던져 바로 잡아서 스택 추적에서 발신자 정보를 추출하십시오.

다른 사람의 의견을 기반으로 업데이트 :도 예외를 포기하고 잡을 필요가 없습니다. new Exception().getStackTrace()이 트릭을 수행합니다.

+0

실제로는 _that_ 못생긴 사실입니다 - Thread.getStackTrace() 구현의 일부입니다 (일반적인 경우는 아님). – Bozho

+0

이전보다 더 적절한 방법이라고 생각하지만 많은 클래스가 클래스 막대를 확장하고 확장 클래스가 발생한다고 상상해보십시오 많은 곳에서 ... 많은 시도/잡기 clausures, 많은 새로운 코드 라인. 우리는 대리인을 concider 수 있지만 가치가 무엇입니까? – kospiotr

+0

@kospiotr'Bar '와 그 하위 클래스들에서 많은 다른 메소드들에서 호출자 정보를 얻으려고한다면,이 솔루션을'Bar'의 단일 보호 메소드에 구현 한 다음 다른 모든 메소드 . 물론 스택 추적 분석기는 배열의 3 번째 항목에서 검색을 시작해야하며 2 번째 항목은 검색하지 않아야합니다 (물론 충분한 요소가있는 경우). –

2

내가 상상할 수있는 가장 강력한 방법은 "this"를 A 내부의 B에 대한 인수로 전달하는 것입니다. 그러면 B가 객체를보고 해당 클래스를 인쇄 할 수 있습니다.

스택 추적을 사용하지 않는 것은 작동하지 않을 수있는 모든 것에 의존합니다. "패스 -이"접근 방식 것입니다.

0

내가 찾은 가장 간단한 방법은 다음 클래스 만드는 것이었다 : API를 기준으로

private static class ClassLocator extends SecurityManager { 
    public static Class<?> getCallerClass() {  
     return new ClassLocator().getClassContext()[2]; 
    } 
} 

을 말한다 배열로 현재 실행 스택을 리턴

"보호 클래스 [] getClassContext을() 배열의 길이는 실행 스택의 메서드 수입니다. 인덱스 0의 요소는 현재 실행중인 메서드의 클래스이고, 인덱스 1의 요소는 해당 메서드의 호출자 등의 클래스입니다. "

http://docs.oracle.com/javase/7/docs/api/java/lang/SecurityManager.html#getClassContext()

관련 문제