是否有可能(如何)在Runtime Java中获得方法引用的名称? [英] Is it possible (how) to get the name of a method reference at Runtime Java?

查看:103
本文介绍了是否有可能(如何)在Runtime Java中获得方法引用的名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近一直在使用许多方法引用和lambda,并想在运行时知道是否可以打印以筛选lambda的来源(即其名称),仅出于调试原因.我认为可以通过在getName()中调用getClass()使用反射来实现,但是我找不到找到原始源引用名称的方法.

I've been using a lot of method references and lambdas recently, and wanted to know at runtime if i could print to screen the source of the lambda ie its name, simply for debugging reasons. I figured it might be possible using reflection, by calling getClass() within getName(), but I couldn't find a method with which to find the original source reference's name.

我有一个功能界面,例如:

I have a functional interface such as:

@FunctionalInterface
public interface FooInterface {
    // function etc etc irrelevant
    public void method();

    public default String getName() {
        // returns the name of the method reference which this is used to define
    }
}

然后可以说我希望测试运行该界面,并将功能界面的源代码打印到屏幕上.

then lets say i wish to test run the interface, and print the source of the functional interface to the screen.

public static void doStuff(FooInterface f) {
    // prints the lambda name that is used to create f
    System.out.println(f.getName());

    // runs the method itself
    f.method();
}

因此,如果我这样做:

doStuff(Foo::aMethodReference);

它应该在屏幕上打印类似"aMethodReference"的内容,这样我就可以在运行时知道正在运行哪些方法,以什么顺序运行.

it should print something like: "aMethodReference" to the screen, that way i can know, at runtime which methods are being run, in what order etc.

考虑到lambda不是完全对象,我非常怀疑这是否可行,但是,我认为可能有解决方法.此外,eclipse调试工具只是说它是lambda,没有任何其他信息,lambda是否保留这些信息中的任何信息吗?还是全部在运行时丢失了?

I'm quite doubtful that this is possible, considering that lambdas are not-quite-objects, but hey, i figured there could be a workaround. Furthermore, the eclipse debug tool just says its a lambda, without any other information, do lambda's retain any of this information? or is it all lost at Runtime?

干杯. (如果使用JDK 11,有什么区别的话)

Cheers. (I'm using JDK 11 if that makes any difference)

推荐答案

正如您所说的,您仅需要将其用于调试目的,这是一个技巧(即肮脏的hack),可让您做自己想做的事情

As you're saying that you only need this for debugging purposes, here is a trick (i.e. a dirty hack) that will allow you to do what you want.

首先,您的功能接口必须为Serializable:

First of all, your functional interface must be Serializable:

@FunctionalInterface
public interface FooInterface extends Serializable {

    void method();
}

现在,您可以使用此未记录的,依赖内部实现的方法和极具风险的 代码来打印有关 targeted 方法参考的一些信息.到FooInterface功能界面:

Now, you can use this undocumented, internal-implementation-dependent and extremely risky code to print some information about the method reference targeted to your FooInterface functional interface:

@FunctionalInterface
public interface FooInterface extends Serializable {

    void method();

    default String getName() {
        try {
            Method writeReplace = this.getClass().getDeclaredMethod("writeReplace");
            writeReplace.setAccessible(true);
            SerializedLambda sl = (SerializedLambda) writeReplace.invoke(this);
            return sl.getImplClass() + "::" + sl.getImplMethodName();
        } catch (Exception e) {
            return null;
        }
    }
}

调用此方法时:

doStuff(Foo::aMethodReference);

您将看到以下输出:

package/to/the/class/Foo::aMethodReference

注1:我在本文作者中看到了这种方法彼得·劳瑞(Peter Lawrey).

注意2:我已经使用openjdk version "11" 2018-09-25java version "1.8.0_192"对此进行了测试.

Note 2: I've tested this with openjdk version "11" 2018-09-25 and also with java version "1.8.0_192".

这篇关于是否有可能(如何)在Runtime Java中获得方法引用的名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆