9

有了新的 java lambdas 和函数式接口的概念,是否可以将这些函数式接口视为方法?

interface Func { void execute(int i); }

void call(Func f)
{
    f(1); //instead of f.execute(1);
}

我发现了很多关于实际 lambda 表达式语法的信息,但对此一无所知。

4

2 回答 2

15

Your proposition

What you propose has been discussed on the lambda-dev mailing list before:

http://mail.openjdk.java.net/pipermail/lambda-dev/2012-February/004518.html

It was mainly rejected because of the various problems related to ambiguity that would arise for the parser / compiler. Or in Brian Goetz's terms:

I think, ultimately, this is just discomfort with the committment to functional interfaces instead of function types, and an attempt to backpedal towards a wishy-washy middle ground. I don't see this as offering a compelling enough benefit.

If you feel that such "wishy-washy" features would still add value to the Java language, you can try your luck again on one of the lambda mailing lists, maybe with compelling arguments :-)

An alternative

It is possible, but probably not as elegantly as in JavaScript as your example syntax suggests. According to the latest state-of-the-lambda by Brian Goetz, there will be method references as mentioned in chapters

8 Method references

[...]

9 Kinds of method references

[...] There are actually three different kinds of method references, each with slightly different syntax:

  • A static method
  • An instance method of a particular object
  • An instance method of an arbitrary object of a particular type

So in fact, your example would have to be rephrased along these lines:

interface Func { void execute(int i); }

void call(Block<Integer> block)
{
    block.run(1); //instead of f.execute(1);
}

You can now pass a reference to that execute method:

// Disclaimer: I didn't check this against a JDK8 compiler...
Func f = (i) -> { ; }; // Empty sample implementation
call(f::execute)

In other words, the "functional" style is to be implemented at the declaration-site of your call method, not at the use-site. But as with JavaScript, the use-site doesn't have to know about the name of the concrete method in Func. It can just accept a Block for methods returning void, or a Callable for methods returning a value.

Note that on JDK's Mercurial repository, things have changed already. You won't find run() any more, as mentioned in the state of the lambda. Other interesting types can be found in the java.util.functions package:

http://hg.openjdk.java.net/lambda/lambda/jdk/file/tip/src/share/classes/java/util/function

于 2012-11-01T09:08:29.963 回答
2

如果我正确理解你的问题,你暗示给定功能接口 Mapper 声明如下

interface Mapper<T,U> {
   public U map(T t);
}

如果我使用 lambda 表达式实现此功能接口,如下所示:

Mapper<Integer,String> itoa = (n) -> String.valueOf(n);

您想调用函数接口如下:

String val = itoa(10); //would yield "10"

而不是今天这样:

String val = itoa.map(10);

我猜,第一次调用是第二次调用的语法糖。

我没有在任何文档或邮件列表中看到他们计划在即将发布的 JDK 中提供此功能。但我想你可以在lambda 邮件列表中提问。我看不出无法实施的原因。

于 2012-11-02T14:25:55.940 回答