views:

163

answers:

2

in java is it possible to make a method aware of who called it (without changing parameters) and then return something else?

public class MyClassA {
   public static final String someStirng = "this is some String"
   public String getSomeString ()
   {
     return someString;
   } 
}

public class MyClassB extends MyClassA {
    public static final String otherstring = "This is other string"
    public SomeBean getContents()
    {
      SomeBean s = new someBean();
      //if this method gets called from MyCallingClassOther then 
      // i want s.setContents(otherstring)
      s.setContents(getSomeString()); 
      return s;
    }
}

public class MyCallingClass {
    public String callingclassContents ()
    {
      MyClassB myb = new MyClassB();
      return ((SomeBean)myb.getContents()).getFirstName();
    }
}

public class MyCallingClassOther {
    public String callingOtherContents ()
    {
       MyClassB myb = new MyclassB();
       return ((SomeBean)myb.getContents()).getFirstName();
    }
}

so when getContents() method of MyClassB gets called from MyCallingClassOther then I want a different thing returned.

Only code I can change is the body of getContents() (cant change parms). or I can change body of callingOtherContents() in MyCallingClassOther.

This is small piece of a bigger puzzle I am trying to solve ...which obviously was designed poorly. This is kind of a hackway.

Also I'd like to see how it is possible in some other languages?

and If you are wondering why I cant change parameters...thats because I do not want to change anything in callingclassContents() of MyCallingClass

+2  A: 

This will give you the information regarding the caller. The "1" would change as needed depending upon how many levels above you want to inquire about.

StackTraceElement aParentStack = new Throwable().fillInStackTrace().getStackTrace()[1];
System.out.println(aParentStack.getClassName());
System.out.println(aParentStack.getFileName());
System.out.println(aParentStack.getLineNumber());
System.out.println(aParentStack.getMethodName());
System.out.println((aParentStack.isNativeMethod() ? "Native" : "Java") + " method");
Taylor Leese
@Taylor: I change your answer a bit to make it more expression. If you don't like it just roll it back. Cheer!
NawaMan
I'm sure that works, but boy is that inelegant. You'd think there'd be a cleaner way to perform this particular runtime introspection.
Justin Searls
-1 because the stack trace may be incomplete or empty. See http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Throwable.html#getStackTrace() for details.
Bombe
+5  A: 

This is small piece of a bigger puzzle I am trying to solve ...which obviously was designed poorly. This is kind of a hackway.

It is possible to do what you want; see @Taylor L's answer. But note that creating an exception in Java doesn't come cheaply.

But my main point is that doing this is almost certainly a bad idea in the long-term. This kind of trickery makes your code harder to understand, and leaves all sorts of little man-traps for people coming after.

IMO, you will be better off changing the method API, and the code that calls it, so that the caller is (in effect) aware of the behavioural differences. In short, fix the bad design, don't make it worse.

Stephen C
"doing this is almost certainly a bad idea in the long-term" -- I agree 100%. The only time it makes sense to resort to this sort of hackery is for debugging.
Laurence Gonsalves
I agree that is not cheap; however, there is such situation when this is the only way to do it.
NawaMan
I would agree with stephen, bad design should not be covered up by hacks.
Suraj Chandran
-1 because a) notes about performance, b) not mentioning that a stack trace *may* actually be incomplete or empty.
Bombe
@Bombe - what? The only circumstance that the stacktrace will be incomplete that I'm aware of is if the exception is an OutOfMemory exception or if the stack is very, very deep. Neither of these seem relevant here. And what is wrong with saying that creating an Exception is not cheap????
Stephen C
If you don’t believe me, read the documentation: http://java.sun.com/javase/6/docs/api/java/lang/Throwable.html#getStackTrace() - VMs are free to omit frames or return an altogether empty array from that method, i.e. *do not rely on it*.
Bombe
I'm fully aware of that. (I should do ... I've actually coded JVMs.) But also I know for a fact that real JVMs only resort to leaving out stack frames in extreme situations ... like when they encounter an extremely deep stack. And even then, they try to keep the top and bottom few frames.
Stephen C