9

新しい Java ラムダと機能インターフェースの概念により、これらの機能インターフェースをメソッドとして扱うことは可能でしょうか?

interface Func { void execute(int i); }

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

実際のラムダ式の構文に関する多くの情報を見つけましたが、これについては何もありません。

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);
}

次のように、ラムダ式を使用してこの機能インターフェイスを実装するとします。

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

次のように関数インターフェイスを呼び出したいとします。

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

そして、今日のようではありません:

String val = itoa.map(10);

最初の呼び出しは、2 番目の呼び出しのシンタックス シュガーだと思います。

JDK の次のリリースでこの機能を提供する予定のドキュメントやメーリング リストを読んだことがありません。しかし、ラムダメーリングリストで質問できると思います。これを実装できなかった理由がわかりません。

于 2012-11-02T14:25:55.940 に答える