简体   繁体   中英

Are reverse method references possible in Java 8?

I know about lambda method references .

However, I am wondering whether the reverse might be possible, because I have a method that just proxies its arguments to a lambda:

Function<Arg, Result> lambda = (a) -> new Result(a);

public Result myMethod(Arg arg) {
    return lambda.apply(a);
}

Haven't found anything on Google, so I guess it's not possible. Which makes sense, because after all, as I understand it, a lambda is just shorthand for a whole interface. A method and an interface are different. But you can make a lambda from a method, so maybe you can make a method from a lambda?

You can't make a method from a lambda because, as you say, a lambda is not a method and more importantly you cannot dynamically change a class by adding methods to it at runtime. That's a basic design invariant of Java classes. It is possible to dynamically respond to a predefined method of an interface with your own implementation, although it's fairly clunky. Take a look at http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html

The variable lambda has the type Function which doesn't say anything about how the instance has been created. It might be a lambda expression, but it doesn't have to. That said, if you want to delegate myMethod to a method declared in Function , there is no reason to automatically choose the abstract method of that interface , so, similar to method references, you would have to specify the target method like lambda::apply to make clear you want that method and not one of the other methods of the interface Function .

But unlike method references, which use a target type, you can't derive a method declaration from the surrounding context, so you can't spare the method declaration. So such a hypothetical feature would still require the method declaration, the reference to the lambda field and the target method name ( apply ), so there is not much left that you can save that would justify a new language feature.

And there is no need for such a functionality anyway. If you have code to be expressed as both, a function and a method, express it as method:

Instead of

Function<Arg, Result> lambda = (a) -> new Result(a);

public Result myMethod(Arg arg) {
    return lambda.apply(a);
}

write

Function<Arg, Result> lambda = this::myMethod;

public Result myMethod(Arg arg) {
    return new Result(arg);
}

But even a code replication might be acceptable, as in

Function<Arg, Result> lambda = (a) -> new Result(a);

public Result myMethod(Arg arg) {
    return new Result(arg);
}

considering that lambda expressions should host rather small, often trivial, code only.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM