views:

388

answers:

3

Suppose that I have a Java class with a static method, like so:

class A
{
    static void foo()
    {
        // Which class invoked me?
    }
}

And suppose further that class A has an arbitrary number of subclasses:

class B extends A { }
class C extends A { }
class D extends A { }
...

Now consider the following method invocations:

A.foo();
B.foo();
C.foo();
D.foo();
...

My question is, how can method foo() tell which class is invoking it?

+9  A: 

It can't, and that's part of the problem with static methods. As far as the compiler is concerned A.foo() and B.foo() are exactly the same thing. In fact, they compile down to the same bytecode. You can't get more similar than that.

If you really need this sort of information, use a singleton and turn foo() into an instance method. If you still like the static syntax, you can build a facade A.foo().

Daniel Spiewak
+2  A: 
class A
{
    static void foo(A whoIsCalingMe)
    {
        // Which class invoked me?
    }
}
Georgy Bolyuba
+2  A: 

Although you can't find out which class the static method was invoked on, it is possible to find out which class actually invoked the method at runtime:

static void foo()
{
   Throwable t = new Throwable();
   StackTraceElement[] trace = t.getStackTrace();
   String className = trace[1].getClassName();
   Class whoCalledMe = null;
   try
   {
      whoCalledMe = Class.forName( className );
   }
   catch( Exception e )
   {
   }
}

I'm not saying that this is good practice and its probably not great from a performance perspective either, but it should work. Don't know if that helps you any ...

alasdairg
Yuck. It works; but IIRC reflection was deliberately made ugly to discourage these sorts of things.
jamesh