我有一个采用功能参数的方法,例如一个 Runnable
。因为它是一种库方法,所以我希望它使用从功能参数派生的记录器。对函数参数调用 getClass
对普通类工作正常,我可以对嵌套类或匿名类调用 getEnclosingClass
;但如果它是一个 lambda 表达式,它会返回一些包含 $$Lambda$
的模糊名称,我可以像这样手动删除它:
Class<?> type = runnable.getClass();
String canonical = type.getCanonicalName();
int lambdaOffset = canonical.indexOf("$$Lambda$");
if (lambdaOffset > 0) {
try {
type = Class.forName(canonical.substring(0, lambdaOffset));
} catch (ClassNotFoundException e) {
// strange, but we can stick to the type we already have
}
}
如您所见,这不是很优雅并且可能不便于携带。我试过 getEnclosingClass
、getEnclosingMethod
和 getEnclosingConstructor
,但它们都返回 null
。
有什么想法吗?
最佳答案
正如 Tassos Bassoukos 已经提到的这是设计使然。
Lambda(类)的字节码是在运行时生成的。所以你得到的是类的实际名称。名称生成为 目标类名 + "$$Lambda$"+ 计数器
。
找一个小片段进行演示。
package sub.optimal;
import static java.lang.System.out;
public class EnclosingClass {
static class InnerRunnable implements Runnable {
@Override
public void run() {
out.println("--- inner class");
}
}
public static void main(String... args) {
showIdentity(() -> System.out.println("--- lambda 1"));
showIdentity(() -> System.out.println("--- lambda 2"));
showIdentity(new InnerRunnable());
showIdentity(new Runnable() {
@Override
public void run() {
out.println("--- anonymous class");
}
});
}
private static void showIdentity(Runnable runnable) {
runnable.run();
Class<? extends Runnable> clazz = runnable.getClass();
out.printf("class name : %s%n", clazz.getName());
out.printf("class hashcode : %s%n", clazz.hashCode());
out.printf("canonical name : %s%n", clazz.getCanonicalName());
out.printf("enclosing class: %s%n", clazz.getEnclosingClass());
out.println();
}
}
输出
--- lambda 1
class name : sub.optimal.EnclosingClass$$Lambda$1/2147972
class hashcode : 2147972
canonical name : sub.optimal.EnclosingClass$$Lambda$1/2147972
enclosing class: null
--- lambda 2
class name : sub.optimal.EnclosingClass$$Lambda$2/10376386
class hashcode : 10376386
canonical name : sub.optimal.EnclosingClass$$Lambda$2/10376386
enclosing class: null
--- inner class
class name : sub.optimal.EnclosingClass$InnerRunnable
class hashcode : 28014437
canonical name : sub.optimal.EnclosingClass.InnerRunnable
enclosing class: class sub.optimal.EnclosingClass
--- anonymous class
class name : sub.optimal.EnclosingClass$1
class hashcode : 19451386
canonical name : null
enclosing class: class sub.optimal.EnclosingClass
关于java - 获取 Java lambda 表达式的封闭类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34589435/