Java中不同参数访问不同方法_引用Java8中具有不同参数的方法

小编典典

引用特定类型的任意对象的实例方法

以下是对特定类型的任意对象的实例方法的引用示例:

String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia",

"Robert", "Michael", "Linda" };

Arrays.sort(stringArray, String::compareToIgnoreCase);

方法参考的等效lambda表达式String::compareToIgnoreCase将具有形式参数列表(String a, String

b),其中a和b是用于更好地描述此示例的任意名称。该方法引用将调用该方法a.compareToIgnoreCase(b)。

但是,::操作员的真正含义是什么?好吧,::运营商可以这样描述(从这个SO问题):

可以以不同的样式获得方法参考,但是它们的含义相同:

静态方法(ClassName::methodName)

特定对象的实例方法(instanceRef::methodName)

特定对象的超级方法(super::methodName)

特定类型(ClassName::methodName)的任意对象的实例方法

类构造函数参考(ClassName::new)

数组构造函数参考(TypeName[]::new)

因此,这意味着该方法引用String::compareToIgnoreCase属于第二类(instanceRef::methodName),这意味着它可以转换为(a,b) -> a.compareToIgnoreCase(b)。

我相信以下示例进一步说明了这一点。甲Comparator包含运行在两个一种方法String的操作数并返回int。可以将其伪描述为(a,b) ==> return int(其中操作数为a和b)。如果您以这种方式查看,则以下所有内容都属于该类别:

// Trad anonymous inner class

// Operands: o1 and o2. Return value: int

Comparator cTrad = new Comparator() {

@Override

public int compare(final String o1, final String o2) {

return o1.compareToIgnoreCase(o2);

}

};

// Lambda-style

// Operands: o1 and o2. Return value: int

Comparator cLambda = (o1, o2) -> o1.compareToIgnoreCase(o2);

// Method-reference à la bullet #2 above.

// The invokation can be translated to the two operands and the return value of type int.

// The first operand is the string instance, the second operand is the method-parameter to

// to the method compareToIgnoreCase and the return value is obviously an int. This means that it

// can be translated to "instanceRef::methodName".

Comparator cMethodRef = String::compareToIgnoreCase;

我们没有描述生成用于实现lambda表达式的对象的字节码(例如,调用内部类的构造函数),而是描述了构造lambda的方法,并将实际构造委托给语言运行时。该配方被编码在invokedynamic指令的静态和动态参数列表中。

基本上,这意味着本地运行时决定如何转换lambda。

Brian继续说:

方法引用与lambda表达式的处理方式相同,不同之处在于,大多数方法引用不需要分解为新方法;我们可以简单地为引用的方法加载一个常量方法句柄,并将其传递给元工厂。

所以,lambda表达式被 脱 到一个 新的方法 。例如

class A {

public void foo() {

List list = ...

list.forEach( s -> { System.out.println(s); } );

}

}

上面的代码将 简化 为以下形式:

class A {

public void foo() {

List list = ...

list.forEach( [lambda for lambda$1 as Consumer] );

}

static void lambda$1(String s) {

System.out.println(s);

}

}

但是,Brian也在文档中对此进行了解释:

如果desugared方法是实例方法,则将接收方视为第一个参数

Brian继续解释说 ,lambda剩余的参数作为参数传递给所引用的方法 。

因此,借助Moandji Ezana的此项,可以将compareToIgnoreCaseas 的废除Comparator分解为以下步骤:

Collections#sort对于一个List期望Comparator

Comparator是方法的功能接口,int sort(String, String)相当于BiFunction

因此,比较器实例可以由BiFunction-compatible lambda提供:(String a, String b) -> a.compareToIgnoreCase(b)

String::compareToIgnoreCase引用带有String参数的实例方法,因此它与上述lambda兼容:String a成为接收方并String b成为方法参数

编辑: 从OP输入后,我添加了一个 低级 示例,说明了 废止

2020-11-01

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值