3

I have three class namely A,B,C and each calls other class methods. Now my problem is getting the caller class name in called method without passing parameters to the called method. Is there any way similar to Class.Type used in apex to get the caller class name?

2
  • You want to get the class name of the class that called the function, or the class of the function being called?
    – sfdcfox
    Nov 25, 2013 at 12:33
  • I hope I can get the class name of the current class. But how to get the class name of the caller class? Nov 25, 2013 at 12:35

3 Answers 3

6

eh, Here's a potential way to do it, but it's ugly. Like troll under a bridge ugly. Like troll under a bridge picking it's nose ugly.

Some languages provide methods on Exception to see the stack frame trace, and through it -- or by parsing it, you can see the calling class. Some (awesome) languages even provide this without executing an exception (cf: Ruby's "caller" method). Apex however, I think, is probably limited to accessing this information via an Exception. What's below is pseudo-code, and I make no guarantees as to it's viability or syntactical correctness. It is, however, of admittedly dubious usefulness and I don't know if one should do it, even if one can.

String stackTrace;
try {
  Integer i = 3/0;
} catch (Exception e) {
  stackTrace = e.getStackTraceString();
}
String[] trace = stackTrace.split('\n');

you can then search for your class name and act on it.

Should you really be doing this?

5
  • Ugly but never thought this eventhough I was using integer.valueOf('x'); to get code flow when the debug log is big Nov 26, 2013 at 5:41
  • I wanted to get the name of the calling class to help in creating unique key names in a caching class. But I don't need a troll picking his nose under a bridge in my code so I'm going to find another way. Nifty trick though. :-)
    – Akrikos
    Aug 6, 2015 at 20:21
  • Nice idea, but my trigger that called from page or from dml update at trace show only one line with current trigger :( Jun 7, 2016 at 9:01
  • Apex has very little reflection capability. The stack trace is one of your only ways to get around the inherent limitations.
    – Shanerk
    Mar 11 at 22:21
  • 1
    I know this is a really old answer, but I was reminded by a comment, and saw your answer, which is what prompted me to look for a better way, because handling div by zero is relatively expensive to do each time. Check out this beauty: String[] trace = new HandledException().getStackTraceString().split('\n')
    – sfdcfox
    Mar 11 at 23:24
4

Scope rules prohibit any means of any piece of code seeing any variable or object declared outside its scope, so it is impossible for a callee to know whom the caller is, unless the caller identifies itself with a parameter. This is true in virtually any language, and especially true in most object-oriented languages. The purpose of the object-oriented design is that each individual class should not need to know about the details of any other class that depends on it, but should provide a known API that dependent classes can use.

In real-world terms, the transmission shouldn't need to know about what kind of car it is installed in, but the car can only use transmissions that conform to certain physical dimensions and properties. Similarly, code should generally not rely on knowing anything about the implementations that use that code. This leads to fragile code because of the two-way relationship that develops.

Of course, sometimes this design is necessary because of the intimate relationship of the two classes. In those cases, each class must still identify itself to the other, because Apex Code's dynamic language constructs do not include inspection of the stack or learning whom the caller is, as opposed to JavaScript, which did have a callee parameter for this purpose. This problem has existed basically since the dawn of modern programming, including C++.

Finally, as a side note, you should also realize that a caller might not be a class at all. Triggers are not classes, yet can also call classes. You wouldn't be able to determine the caller in that case, because they aren't normal classes.

4
  • 1
    For logging classes and the like its pretty relevant to know the caller or even the entire call tree. Grabbing the stack trace is a good tool in lieu of native reflection, or doing something like passing "this" as a parameter. This is something other languages most certainly DO have: stackoverflow.com/questions/171970/…
    – Shanerk
    Mar 11 at 22:23
  • @Shanerk My problem with exceptions is that they are really expensive compared to what reflection would offer. Also, I think as of a few years ago, stack traces in a trigger only go to the trigger level, not any further. That said, throwing an exception can at least get a stack string that can be parsed.
    – sfdcfox
    Mar 11 at 23:02
  • @Shanerk Actually, I just tested another solution that's actually significantly fast. It's similar to the other answer, but with a major improvement. Thanks for bringing my attention to this decade-old answer.
    – sfdcfox
    Mar 11 at 23:11
  • Thanks, any new reflection capabilities, tricks or workarounds in Apex are always of interest to me and relevant to my daily work.
    – Shanerk
    Mar 12 at 13:17
0

Incorporating the latest ideas from @sfdcfox, here is a complete solution you can drop into any class, such as a logging class:

  public final String CLASS_NAME = String.valueOf(this).substring(0, String.valueOf(this).indexOf(':'));

  public String getCallingClassName() {
    String[] trace = new HandledException().getStackTraceString().split('\n');
    for (String s : trace) {
      // Skip lines that correspond to this class
      if (s.contains('Class.' + CLASS_NAME + '.')) continue;
      try {
        // Return the class name from the first line NOT corresponding to this class, ignore the rest of the trace
        return s.split(':')[0].split('\\.')[1];
      } catch (Exception ex) {}
    }
    return 'Unknown';
  }

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .