我有一个采用功能参数的方法,例如a 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(类)的字节码是在运行时生成的.所以你得到的是班级的实际名称.并且名称生成为target class name + "$$Lambda$" + a counter
.
找一个小片段进行演示.
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