如何获取lambda导致的方法名称

Mig*_*boa 6 lambda java-8

从简单的角度来看,lambda表达式被编译成static方法,因为它们不捕获this(即不访问实例成员).

public class App {
  public static void foo(){
      Consumer<Integer> c1 = n -> {};
      Consumer<Integer> c2 = n -> {};
  }

  public static void main(String [] args) {
    Supplier<String> sup1 = () -> "I am sup1";
    Supplier<String> sup2 = () -> "I am sup2";
    Supplier<String> sup3 = () -> "I am sup3";

    Stream.of(App.class.getDeclaredMethods()).forEach(System.out::println);
  }
}
Run Code Online (Sandbox Code Playgroud)

运行前面的例子,并检查与生成的字节码javap工具,我们可以看到,通过变量称为lambda表达式c1,c2,sup1,sup2,sup3被编译成与名称的方法:

  • lambda$foo$0
  • lambda$foo$1
  • lambda$main$2
  • lambda$main$3
  • lambda$main$4

然而,如果我们打印出getClass()由这些变量称为每个对象(c1,c2,sup1,sup2,sup3)我们会得到,分别为:

  • class App$$Lambda$5/1705736037
  • class App$$Lambda$6/455659002
  • class App$$Lambda$1/791452441
  • class App$$Lambda$2/531885035
  • class App$$Lambda$3/1418481495

那么,我们如何才能使运行时类名称和lambda所产生的方法名称之间的对应关系?

UPDATE

以下重复问题中指出的解决方案都没有帮助我解决我在问题中提出的问题:

我找到的唯一方法是将@Holger的解决方案从其答案(不是可接受的)调整到Java 8的问题:将lambda转换为包含clousure的Method实例.但是,在我的情况下,Method我只是在寻找方法的名称而不是对象.所以,lambdaToMethod()根据以下情况调整methodNameFromLambda()我得到了一个解决方案:

static String methodNameFromLambda(Serializable lambda) {
  try {
    Method m = lambda.getClass().getDeclaredMethod("writeReplace");
    m.setAccessible(true);
    SerializedLambda sl=(SerializedLambda)m.invoke(lambda);
    return sl.getImplMethodName();
  } catch(ReflectiveOperationException ex) {
    throw new RuntimeException(ex);
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,例如lambda表达式必须强制转换Consumer<Integer>&SerializableSupplier<String>&Serializable在@Holger描述答案.

我不知道这个解决方案是否正确,但它适用于我的示例和我正在处理的案例.

Eug*_*ene 4

这可能会因版本而异 - 没有规范说明确切的名称- 并且这是故意这样做的;可以很好地防止代码发现与这些名称有关的聪明的事情。

  • @Miguel Gamboa:所有链接的问答的底线是根本没有通用的解决方案,只有具有特定缺点的部分解决方案。如果有人找到更好的解决方案,则应将其添加到现有问题之一中。结束语的目的是避免同一件事的答案分散在多个问题中(比我们已经拥有的更多)...... (2认同)
  • @Eugene:[此评论](/sf/ask/1389164941/#comment36054089_19845393)钉住了它——这只是一个完全不同的功能。对于“Supplier”实例,无法保证它已被实现为 lambda/方法引用,也无法保证创建者愿意允许对应该是实现细节的事物进行这种反射。[这个答案](/sf/answers/3311868731/)也说明了这个问题,对于语义相同的表达式,你会得到三个不同的答案...... (2认同)