tags:

views:

270

answers:

5

I would like some help on this matter,

Example:

public class A {

    private void foo() {

          //Who Invoked me

    }

}

public class B extends A { }

public class C extends A { }

public class D {

     C.foo();

}

This is basically the scenario. My question is how can method foo() know who is calling it?

EDIT: Basically I am trying to do a database Layer, and in Class A I will create a method that will generate SQL statements. Such statements are dynamically generated by getting the values of all the public properties of the calling class.

+6  A: 

Easiest way is the following:

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

But in real there should be no need for this, unless for some logging purposes, because this is a fairly expensive task. What is it, the problem for which you think that this is the solution? We may come up with -much- better suggestions.

Edit: you commented as follows:

basically i'am trying to do a database Layer, and in Class A i will create a method that will generate sql statements, such statements are dynamically generated by getting the values of all the public properties of the calling class.

I then highly recommend to look for an existing ORM library, such as Hibernate, iBatis or any JPA implementation to your taste.

BalusC
basically i'am trying to do a database Layer, and in Class A i will create a method that will generate sql statements, such statements are dynamically generated by getting the values of all the public properties of the calling class.
Mark Buhagiar
Do exceptions fill the stack trace in the constructor? Or only when thrown?
Martinho Fernandes
@Mark: that's really bad design. I would ***deeply*** reconsider it.
Martinho Fernandes
How about `Thread.currentThread().getStackTrace()[0]`? Saves us from creating an Exception just for the stack trace.
Peter Kofler
... and also removes the need to know when the stack trace of an `Exception` is created (at creation) ;-)
Peter Kofler
@Peter: `Thread.currentThread().getStackTrace()[0].getMethodName()` is always `"getStackTrace"`. Guess you can figure out why...
Martinho Fernandes
@Mark, this gives you the NAME of the class but not the INSTANCE. In other words, WHICH object will you get the public fields from. You should pass in a data object.
Thorbjørn Ravn Andersen
A: 

From a stack trace: http://www.javaworld.com/javaworld/javatips/jw-javatip124.html

quant_dev
+4  A: 

foo() is private, so the caller will always be in class A.

mathepic
Class D wouldn't have compiled.
BalusC
+11  A: 

Perhaps for your use case it would make sense to pass the class of the caller into the method, like:

public class A { public void foo(Class<?> c) { ... } }

And call it something like this:

public class B { new A().foo(getClass() /* or: B.class */ ); }
Fabian Steeg
+1 for +pointing out the *right* way to do it. Let's not mess up with stack traces for something like this.
Martinho Fernandes
Yes. If caller must pursue the basic design which uses reflection to perform the task, let the linkage be clear. Pass the class, or an instance.
CPerkins
In general I would agree with you, but if you are creating a framework of the sorts it can become useful
mfeingold
@mfeingold: name an example that would work better by inspecting the call stack than getting the class as a parameter
Martinho Fernandes
+1, the only reason to use a stack trace is in a debugging scenario.
Yishai
Why are you talking about a Class parameter anyway? He needs the Object of type D, so he can read the property values. I think Mark confused Class/Object anyway, or is everything *static* there?
mhaller
@mhaller, theoretically you could want to create a new object (say if the object had to have a public no-arg constructor), and it could be called from a static factory.
Yishai
A: 

In .Net we can do it with StackTrace class. It gives you direct access to reflection info without any parsing. Is there anything similar in Java?

mfeingold
Sure, read the earlier answers.
Jim Ferrans