在Java中,无需使用(即键入)类名就可以访问该类。一个例子
public class Example {
/**
* Non static context, can only be called from an instance.
*/
public void accessClass() {
System.out.println(this.getClass());
}
}
但是,在静态上下文中没有类似的方法,只有.class静态字段。这个问题的重点是从java类本身而不是其他类访问.class。
public class Example2 {
//field used to demonstrate what is meant by "indirectly referencing the class name.
private static Class<Example2> otherClass = Example2.class;
private static int intField = 1;
/**
* Non static context, can only be called from an instance.
*/
public static void accessClass() {
// The .class static field can be accessed by using the name of the class
System.out.println(Example2.class);
// However the following is wrong
// System.out.println(class);
// Accessing static fields is in general possible
System.out.println(intField);
// Accessing a static field of the same Class is also possible, but does not satisfy the answer since the class name has been written in the declaration of the field and thus indirectly referenced.
System.out.println(otherClass);
}
}
是否有一种方法可以从同一个类的静态上下文访问一个类的.class
对象,而无需引用类名(直接或间接)?
另一个限制是不允许答案实例化该类或使用.getClass()
实例方法。
我在上面创建了一些示例,试图证明我的发现。
令我感到惊讶的是,如果没有在同一个类中输入类名,我将找不到访问.class
字段的方法。
这仅仅是某些设计决策的副作用吗?或者是否有根本原因导致没有类名就无法访问.class
?
答案 0 :(得分:2)
我发现的一种方法是首先获取当前堆栈跟踪:
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
StackTraceElement current = stackTrace[1];
然后,调用getClassName
并将其传递给Class.forName
:
Class<?> clazz = Class.forName(current.getClassName());
答案 1 :(得分:2)
使用StackWalker
API的Java 9方法
Class<?> currentClass = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE)
.walk(s -> s.map(StackFrame::getDeclaringClass).findFirst().orElseThrow());
这种方法避免完全使用类名。
由于whis不是核心语言功能的原因,我只能猜测,但是我想到的一件事是嵌套类的一些复杂性,这些复杂性会使通过某些关键字实现这种功能变得复杂。如果没有一种方法可以从嵌套类等中引用多个外部类,则添加它就没有多大意义。
另一个原因是,此功能不是非常有用-这不是我从未错过的功能。使用当今的IDE及其强大的重构工具,即使以后重命名了类,使用类名也不会造成太大问题。即使在生成源代码时,替换类名也相对简单。