在Java 8中以静态方式获取class名称

Get class name in a static way in Java 8

这是 more general and similar question/answers

的跟进

Java 8 中,我可以使用 new Exception

获得调用方法的 class 名称
String className = new Exception().getStackTrace()[1].getClassName();

但是我可以静态获取class名字吗?

编辑

如果我在另一个 class 的方法中并且想知道 class 调用了我的方法

以静态方式从另一个 class 获取调用 class 的 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());
    }
}

以静态方式获取完全限定 class 名称的示例:

MyClass.class.getName();

获取调用堆栈的Java9+技术使用StackWalker 使用 StackWalker 的等价物如下:

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());
                   });
    }
}

使用StackWalker的优点是它可以延迟生成堆栈帧。这避免了 Thread.getStackTrace() 在创建大量堆栈帧时产生的开销。如果调用堆栈很深,并且您只想查找几个帧(如本例所示),那么创建完整的堆栈跟踪尤其浪费。