8

I have following classes (note that methods are static):

class Base
{
   public static void whosYourDaddy()
   {
      Class callerClass = // what should I write here to get caller class?
      System.out.print(callerClass.getName());
   }
}

Class A extends Base
{
   public static void foo()
   {
      A.whosYourDaddy();
   }
}

Class B extends Base
{
   public static void bar()
   {
      B.whosYourDaddy();
   }
}

And when I call:

A.foo();
B.bar();

I'd like to get output: AB instead of BaseBase. Is it even possible with static methods (in Java 7)?

Greg Witczak
  • 1,634
  • 4
  • 27
  • 56

3 Answers3

7

What you can do, but shouldn't :) is use the Throwable getStackTrace method. Aside from the smell, this is pretty slow, because getting the stack trace isn't that fast. But you will get an array of StackTraceElement, and each one will contain the class of teh class that is calling it (and you can also get the file and line, and if you separate the two with a : you can get a clickable link in eclipse, not that I'd ever do such a thing...).

Something like

String className = new Throwable().getStackTrace()[1].getClassName(); 

Hope that helps :)

Ben Brammer
  • 988
  • 4
  • 11
  • 1
    Witchery! :) *Aside from the smell, this is pretty slow, because getting the stack trace isn't that fast.* Actually, I think it's only slow the first few times it runs. I believe HotSpot has optimisations for this. Let me have a look for the reference... – Muel Sep 05 '13 at 23:52
  • Reference for the previous comment: http://www.javaspecialists.eu/archive/Issue187.html – Muel Sep 06 '13 at 00:04
  • Of course I'm speculating about the speed because I would never do such a thing, not even if it were to really simplify printf-style debugging in eclipse, but if I had, I wouldn't have measured it; I merely would have surmised that the cost of arbitrary getStackTrace calls might be significant. Thanks for the reference. – Ben Brammer Sep 06 '13 at 15:41
  • The sorcery is strong with this one. Knowing this kind of magic may come handy, I know its reinventing the wheel and totally crashing through the class hierarchy but, still. – Felype Apr 23 '15 at 14:18
0

 private static class Reflection {
    private static final SecurityManager INSTANCE = new SecurityManager();
    static Class getCallClass() {
        return INSTANCE.getCallClass(2);
    }
    private Reflection() {
    }
    private static class SecurityManager extends java.lang.SecurityManager {
        public Class getCallClass(int i) {
            Class[] classContext = getClassContext();
            if (i >= 0 && i + 1 < classContext.length) {
                return classContext[i + 1];
            }
        return null;
        }
    };
}
Darin Kolev
  • 3,401
  • 13
  • 31
  • 46
zhanhb
  • 1
-1

Is it even possible with static methods (in Java 7)?

No, Static methods aren't inherited. Only non-static methods are inherited.

In your case change Base (and subclasses) as follows:

class Base
{
  public void whosYourDaddy()
  {
    Class<?> callerClass = getClass();
    System.out.print(callerClass.getName());
  }
}
Muel
  • 4,309
  • 1
  • 23
  • 32