4

I know I can get the method and classname from StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); but that is not what I want. I want the class object, so I can access his interface, annotations, etc...

It is possible? Class<?> classObject = getCallerClass();

I see this question, but that is just for the classname.

How to get the caller class in Java

Edit: Now I'm passing the class this way:

someService.dummyMethod(foo1, foo2, new Object(){}.getClass());

  someService(String foo1, int foo2, Class<?> c) {
    // stuff here to get the methodname, 
    // the interface of the class and an annotation from the interface.
}

I call someService from a lot of different classes, If is not possible I will continue this way, but If there is a way to get the caller class at runtime I prefer that way.

FranAguiar
  • 637
  • 3
  • 14
  • 31
  • the "class Object"? what exactly do you mean by that? Either way, why can't you get it from what you get out of the stackTrace? – Stultuske Aug 09 '18 at 13:15
  • 3
    I would strongly advice against doing such things. What you try to do here is a clear sign for a **bad architecture**. If a method needs a reference to its caller, it should demand it as **parameter** and the caller then should provide himself: `foo(this);`. – Zabuzard Aug 09 '18 at 13:15
  • Note that a `Class>` object does only represent the class, not the instance. It sounds that you want to get the instance. So you would probably need something like a `Reference>`. – Zabuzard Aug 09 '18 at 13:17
  • No, I want the class, not an instance. – FranAguiar Aug 09 '18 at 13:18
  • 1
    I think you already have the classname at hand, don't you? You can retrieve the `Class` object, given the name. See [Getting class by its name](https://stackoverflow.com/questions/10119956/getting-class-by-its-name). – Zabuzard Aug 09 '18 at 13:26
  • 1
    Carefully read through the complete question you linked ([How to get the caller class in Java](https://stackoverflow.com/questions/11306811/how-to-get-the-caller-class-in-java)). Some of the answers show how to retrieve the `Class` object, not only the name. – Zabuzard Aug 09 '18 at 13:32
  • Why are you now doing `new Object(){}.getClass()`? That's the class of an anonymous class of `Object`, not the class of your current instance. Use `this.getClass()` or `Foo.class`. – Zabuzard Aug 09 '18 at 13:33

2 Answers2

7

If you're using Java 9+ you can use java.lang.StackWalker.

public void foo() {
    Class<?> caller = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE)
            .getCallerClass();
}

However, since StackWalker is thread safe it might be beneficial to create an instance and store it somewhere (rather than create a new instance every time the method is called).

Javadoc of getCallerClass():

Gets the Class object of the caller who invoked the method that invoked getCallerClass.

This method filters reflection frames, MethodHandle, and hidden frames regardless of the SHOW_REFLECT_FRAMES and SHOW_HIDDEN_FRAMES options this StackWalker has been configured with.

This method should be called when a caller frame is present. If it is called from the bottom most frame on the stack, IllegalCallerException will be thrown.

This method throws UnsupportedOperationException if this StackWalker is not configured with the RETAIN_CLASS_REFERENCE option.

Slaw
  • 37,820
  • 8
  • 53
  • 80
6

Get the classname using the code of your linked question: How to get the caller class in Java

Then use the classname to retrieve the class, using code from here: Getting class by its name

Complete code:

String callerName = Thread.currentThread().getStackTrace()[2].getClassName();

try {
    Class<?> caller = Class.forName(callerName);
    // Do something with it ...
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

(community answer, since only mix of existing answers).

Zabuzard
  • 25,064
  • 8
  • 58
  • 82