java - 获取 Java lambda 表达式的封闭类

标签 java lambda

我有一个采用功能参数的方法,例如一个 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
    }
}

如您所见,这不是很优雅并且可能不便于携带。我试过 getEnclosingClassgetEnclosingMethodgetEnclosingConstructor,但它们都返回 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/

相关文章:

node.js - 无服务器函数在 lambda 上总是超时

java - 使用 Stream.filter 时出现错误 -> "com.google.gson.internal.LinkedTreeMap cannot be cast to"

java - 使用 JAVA 和 SSL 连接 MQ 版本 9

python - Lambda 排除包含字符串列表的值

c++ - 从 lambda 返回值与声明位于同一行

python - f = lambda n :(1, f(n-1)*n)[n>1] 在 Python 3 中给出 RunTimeError

c# - EF Core 7 - 仅包含未删除的项目

java - 如何确保对多列(mm_book_id 和 mm_author_id)应用唯一约束?

java - 将 java 和 clojure 文件混合在一个包中

java - jtextarea.append(variable) 与 System.out.println(variable) 有何不同?