2

This is a follow up to more general and similar question/answers

In Java 8 I can get class name called the method using new Exception

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

But can I get class name in a static way?

edit

If I'm inside a different class's method and want to know the class called my method

Ori Marko
  • 56,308
  • 23
  • 131
  • 233
  • Based on your comment to an answer below, is it safe to say that you're asking for a way to statically determine the classname of a calling class from within a method call? – Gus Oct 03 '19 at 18:22
  • @gus yes exactly – Ori Marko Oct 03 '19 at 18:24
  • I don't think you can do that statically, but you can do it without having to create an `Exception` using `Thread.currentThread().getStackTrace();` – Gus Oct 03 '19 at 18:30
  • "know the class called my method" how should that work in a static way? A method can be called from a lot of other classes, only what I can think of is that each calling class must pass its classname as an argument to the called method – user85421 Oct 03 '19 at 18:40
  • 1
    @CarlosHeuberger StackWalker in Java 9 – Ori Marko Oct 03 '19 at 18:46
  • @user7294900 the name itself `...Walker` suggest that it is not statically or in a "static way", more like dynamic (but maybe I am misunderstanding what is meant by static) – user85421 Oct 03 '19 at 18:50
  • @NathanHughes I want dynamically on runtime to know class mame – Ori Marko Oct 03 '19 at 18:53
  • dynamically? wasn't it static? I would think they are opposite, am I really that bad at English? – user85421 Oct 03 '19 at 19:02
  • @CarlosHeuberger get class name on runtime using static method – Ori Marko Oct 03 '19 at 19:05
  • never mind I probably also have a different understanding what a `static` method is (sure not `element.getClassName()`) and its too late for me to get it anyway – user85421 Oct 03 '19 at 19:09

2 Answers2

4

Example for getting the class name of the calling class in a static way from another class:

public class Main {
    public static void main(String[] args) {
        example();
    }

    public static void example() {
        B b = new B();
        b.methodB();
    }
}

class B {
    public void methodB(){
        System.out.println("I am methodB");
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        StackTraceElement element = stackTrace[2];
        System.out.println("I was called by a method named: " + element.getMethodName());
        System.out.println("That method is in class: " + element.getClassName());
    }
}

Example for getting the fully qualified class name in static way:

MyClass.class.getName();

Ritesh Puj
  • 126
  • 5
1

The Java9+ technique of getting the call stack uses StackWalker. The equivalent of Ritesh Puj's answer using StackWalker is as follows:

public class Main {
    public static void main(String[] args) {
        example();
    }

    public static void example() {
        B b = new B();
        b.methodB();
    }
}

class B {
    public void methodB(){
        System.out.println("I am methodB");
        StackWalker.getInstance()
                   .walk(frames -> frames.skip(1).findFirst())
                   .ifPresent(frame -> {
                        System.out.println("I was called by a method named: " + frame.getMethodName());
                        System.out.println("That method is in class: " + frame.getClassName());
                   });
    }
}

The advantage of using StackWalker is that it generates stack frames lazily. This avoids the expense that Thread.getStackTrace() incurs when creating a large array of stack frames. Creating the full stack trace is especially wasteful if the call stack is deep, and if you only want to look up a couple frames, as in this example.

Stuart Marks
  • 127,867
  • 37
  • 205
  • 259