java怎样创建委托_Java 8中有委托吗?

Java 8中有委托吗?

如果没有,我们如何在JDK 8中使用不带委托的lambda表达式?

什么是方法参考? 他们和代表们一样吗?

功能接口是委托。 实际上,普通的旧接口也可以是委托。

@Pacerier:我的第一个反应是认为您指的是委托的更一般含义,而不是lambda表达式中涉及的单功能委托。 我遇到了必须使用Java 7并执行C#代表所做的事情,而您的评论确实帮助我了解了如何在没有Java 8 lambda的情况下如何最好地做到这一点。 在下面添加一个答案,以详细说明我对您的意思的理解。

在JDK 8中没有委托。在底层,lambda是功能接口的实例(一种具有一种抽象方法的接口)。根据传递lambda的位置,编译器可以确定其实现的接口。例如,Collections.sort方法接受Comparator实例作为第二个参数。比较器恰好是一个功能接口,因此编译器将检查您传递的lambda是否与比较器中的抽象方法匹配。

方法参考只是一种简化。当您的lambda只是调用现有方法时,您可以使用此新语法简化构造。

链接教程中的示例很好地说明了这一点:

代替:

Arrays.sort(rosterAsArray,

(a, b) -> Person.compareByAge(a, b)

);

使用方法参考更简单:

Arrays.sort(rosterAsArray, Person::compareByAge);

看看lambdafaq。

关于Java 8中的代表?

JDK 8中没有委托,他们使用提到的功能接口来拥有lamdbas。

Lambda转换为对生成的私有方法的方法引用,因此,如果可以使用它,则方法引用的效率会稍高一些。

..但是请看我的答案,即使在Java 7中,您离实现C#委托所做的工作有多近。

感谢Pacerier对这个问题的评论,这是一种即使在Java 7或更低版??本中也可以完成C#(单功能)委托所做的工作的方法。

// This defines the 'delegate'.

public interface IA {

int f(int a);

}

public class MyClass {

// f1 and f2 have the same signature as 'IA.f'.

private int f1(int a) {

return a + 1;

}

private int f2(int a) {

return 2 * a;

}

// These wrappers are one way to return a 'delegate'.

// Each wrapper creates one instance of an anonymous class.

// Notice that we did not have to declare MyClass as implementing IA,

// and that we can wrap different methods of MyClass into 'IA's.

// Contrast this with 'MyClass implements IA', which would require

// a method 'f' in 'MyClass', and would not provide a way to

// delegate to different methods of 'MyClass'.

public IA wrapF1() {

return (new IA(){

public int f(int a) {

return f1(a);

}

});

}

public IA wrapF2() {

return (new IA(){

public int f(int a) {

return f2(a);

}

});

}

// returns a 'delegate', either to 'f1' or 'f2'.

public IA callMe(boolean useF2) {

if (!useF2)

return wrapF1();

else

return wrapF2();

}

}

用法

...

// Create and use three 'delegates'.

// Technically, these are not quite the same as C# delegates,

// because we have to invoke a method on each.

// That is, we must do 'ia0.f(..)' instead of 'ia0(..)'.

// Nevertheless, it satisfies the design requirement.

MyClass c = new MyClass();

IA ia0 = c.wrapF1();

IA ia1 = c.callMe(false);

IA ia2 = c.callMe(true);

int result0 = ia0.f(13);

int result1 = ia1.f(13);

int result2 = ia2.f(13);

产量

result0: 14    

result1: 14    

result2: 26    

注意:如果您仅需要给定"委托"的每个类的单个实现,则更简单的解决方案是直接在该类上实现接口。这是一个例子。该类已经具有f3,现在可以扩展为实现IA:

public class MyClass2

implements IA {

private int baseValue;

private int anotherValue;

public MyClass2(int baseValue, int anotherValue) {

this.baseValue = baseValue;

this.anotherValue = anotherValue;

}

public int f3(int v1, int v2) {

return 2 * v1 + v2;

}

public int f(int a) {

return f3(baseValue + a, anotherValue);

}

}

IA ia3 = new MyClass2(10, 3);

int result3 = ia3.f(13);   // = f3(10 + 13) = 2 * 23 + 3 = 49

在这种情况下,它与任何其他接口实现没有什么不同。关键是,使用Java接口,只需额外进行一些编码,就可以满足design concept返回与指定签名匹配的函数。在第二种更简单的情况下,将接口直接放置在类上。在第一种更一般的情况下,将接口放置在匿名内部类的匿名实例上。为了清楚和易于访问,我在包装函数中隔离了这些"委托创建者"。

的确,结果与C#委托并不完全相同,因为必须执行ia.f()而不是ia()。尽管如此,已经达到了设计目标。

注意:在Java 8中,使用lambda简化了编码。我没有使用Java 8,因此这里不包括Java 8实现。 (欢迎任何人提交添加该实现的编辑。我建议在下面显示上述wrapF1()和wrapF2()的新内容,因为这样可以轻松比较Java 7和Java 8版本。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值