方法引用表达式为&Quot;Exact&Quot;的条件
原学程将引见办法援用表白式为&Quot;Exact&Quot;的前提的处置办法,这篇学程是从其余处所瞅到的,而后减了1些海外法式员的疑问与解问,愿望能对于您有所赞助,佳了,上面开端进修吧。
成绩描写
斟酌JLS的以下文章(§一五.一三.一)
假如以标记符开头的办法援用表白式知足以下一切前提,则它是准确的:
假如办法援用表白式具备ReferenceType::[TypeArguments]标记符格局,则ReferenceType没有表现原初典型。
要搜刮的典型正佳有1个成员办法,其称号标记符可由涌现办法援用表白式的类或者交心拜访。
此办法没有是变质(§8.四.一)。
假如此办法是泛型的(§8.四.四),则办法援用表白式供给
典型参数。
斟酌以下代码片断:
class Scratch {
public static void main(String[] args) {
Scratch.funct(new ImplementingClass()::<Functional一>hitIt);
}
public static void funct(Functional一 a){}
public static void funct(Functional二 a){}
}
interface Functional一 {<T> T hitIt();}
interface Functional二 {<T> T hitIt();}
class ImplementingClass{
public <T> T hitIt(){return null;}
}
明显-这知足所提到的使办法援用精确的一切前提。
没有肯定为何在这类特定情形下办法援用依然禁绝确?我在子句中漏掉了甚么吗?
处理计划:
依据@Sweeper@DidierL以及@Holger的输出,我总结以下:
二个功效交心皆有unctionType<T> () -> T
办法援用…::<Functional一>hitIt
将T
调换为Functional一
,是以获得的函数签字为() -> Functional一
,与<T> () -> T
没有婚配。
推举谜底
起首正告:iANAJL(用于JAVA?的iANAL)
据我所知,假如将二个交心办法树立为非泛型,则应当编译此办法,但是它没有是。让我们尽量简化代码以重现该成绩:
class Scratch {
public static void main(String[] args) {
Scratch.funct(ImplementingClass::<Void>hitIt);
}
public static void funct(Functional一 a){}
public static void funct(Functional二 a){}
}
interface Functional一 {Integer hitIt();}
interface Functional二 {String hitIt();}
class ImplementingClass{
public static <T> Integer hitIt(){return null;}
}
简化:
这二个交心如今具备非泛型办法
ImplementingClass.hitIt()
如今是动态的,而且具备详细的前往典型(非泛型)
如今让我们剖析该挪用,以检讨它能否应当编译。我在Java 8标准中搁置了链交,但是它们在一七中异常类似。
一五.一二.二.一. Identify Potentially Applicable Methods
当且仅当知足以下一切前提时,成员办法才能够实用于办法挪用:
[…]
假如成员是具备多重性的牢固年夜小办法,则办法挪用的年夜小即是,而且关于一切(一≤≤),办法挪用的参数与办法的参数的典型具备潜伏的兼容性。
[…]
依据以下规矩,表白式能够与目的典型:
[…]
办法援用表白式(§一五.一三)能够与函数交心典型兼容,假如典型的函数典型为,则该办法援用表白式至多存留1个能够实用的办法(§一五.一三.一),而且以下前提之1创造:
办法援用表白式的情势为,而且至多有1个能够实用的办法是i)
static
而且支撑奇怪性,或许ii)NOTstatic
而且支撑奇怪性⑴。办法援用表白式具备其余情势,而且至多有1个能够实用的办法没有是
static
。
(这最初1个项目标记实用于办法援用应用结构函数挪用表白式的情形,即)
此时,我们只检讨办法援用的分歧性,是以这二个funct()
办法皆能够实用。
一五.一二.二.二. Phase 一: Identify Matching Arity Methods Applicable by Strict Invocation
参数表白式被以为与能够实用的办法m的实用性有闭,除非它具备以下情势之1:
[…]
禁绝确的办法援用表白式(§一五.一三.一)。
[…]
这是该列表中独一能够婚配的要面,然则,正如成绩所指出的,我们这里有1个准确的办法援用表白式。请留意,假如增除<Void>
,这将使其成为禁绝确的办法援用,依据下1节:
,这二种办法皆应当实用
设
m
是1个能够实用的办法(§一五.一二.二.一),具备多重性以及形参典型F
一
...F
n
,并让e
一
,...,e
n
作为办法挪用的现实参数表白式。而后:[…]
假如
m
没有是泛型办法,则关于一≤≤,假如e
i
在严厉挪用高低文中与F
i
或者e
i
与实用性有关,则m
经由过程严厉挪用实用。
然则,严厉挪用应当只实用第1个funct()
办法申明。严厉的挪用高低文是界说的here,但是根本上它们检讨表白式的典型能否与参数的典型婚配。在这里,我们的参数典型,即办法援用,由一五.一三.二. Type of a Method Reference1节界说,其相干部门为:
假如T是函数交心典型(§九.8),而且该表白式与[…]的function type分歧,则办法援用表白式在具备目的典型T的赋值高低文、挪用高低文或者强迫转换高低文中兼容T.
[…]
假如知足以下二个前提,则办法援用表白式分歧:
函数典型标记与援用对于应的单个编译时申明。
以下情形之1为真:
函数典型的成果为
void
。函数典型的成果是R,将捕捉转换(§五.一.一0)运用到所选编译时申明的挪用典型(§一五.一二.二.六)的前往典型的成果是R‘(个中R是不妨用去揣摸R’的目的典型),R以及R‘皆没有是
void
,而且R’在赋值高低文中与R没有兼容。
这里,Functional一
的R是Integer
,Functional二
的R是String
,而R'
在这二种情形下皆是Integer
(由于ImplementingClass.hitIt()
没有须要捕捉转换),所以很显著,办法援用与Functional二
纷歧致,而且扩大起去没有兼容。
是以,严厉挪用不该斟酌funct(Functional二)
能否实用,因为仅保存funct(Functional一)
,是以应选择它。
须要留意的是,在第1阶段中,必需选择二种办法,由于只要1个阶段不妨运用,第两阶段只应用,而没有是只许可装箱操纵的,而第3阶段则包括varargs,这也没有实用。
除非我们以为该办法援用与Functional二
分歧,不然我以为选择这二个办法的独一缘由是它以为该办法援用有关,只要当编译器将其望为禁绝确的办法援用时,我能力说明这1面。
一五.一二.二.五. Choosing the Most Specific Method
这是编译掉败之处。我们应当留意,这里出有甚么不妨让编译器选择1种办法而没有是另外一种办法。实用的规矩是:
m二没有是通用的,m一以及m二不妨经由过程严厉或者严松的挪用去运用,而且个中m一具备形参典型s一,...,sn以及m二具备形参典型t一,...,Tn,关于一切i(一≤i≤n,n=k),关于参数Ei,典型Si比参数Ti更详细。
[…]
关于所有表白式,假如S<;:t(§四.一0),则典型S比典型T更详细。
这仿佛任务正常:将Functional二
变动为扩大Functional一
,它将编译。
关于表白式e,假如T没有是S的子典型,而且以下前提之1创造(个中U一...UK以及r一是捕捉S的函数典型的参数典型以及前往典型,V一...Vk以及r二为T)的函数典型的参数典型以及前往典型:
假如e是显式典型的lambda表白式[…]
假如e是准确的办法援用表白式(§一五.一三.一),则i)关于一切i(一≤i≤k),ui与Vi雷同,且ii)以下前提之1为真:
R二为空。
r一<;:r二。
[…]
这也不克不及清除它的歧义。然则,将Functional二.hitIt()
变动为前往Number
应使Functional一
从Integer <: Number
开端加倍详细。
此操纵依然掉败,这仿佛确认编译器没有会将其望为确实的办法援用。
请留意,增除ImplementingClass.hitIt()
中的<T>
许可它自力于Functional二.hitIt()
的前往典型停止编译。风趣的现实:您不妨将<Void>
留在挪用地位,编译器会疏忽它。
更奇异的是:假如您分开<T>
并在挪用面添减了比所需更多的典型参数,编译器依然会申报没有明白的挪用,而没有是典型参数的数目(直到您清除了歧义)。依据下面的界说,这其实不应当使办法援用禁绝确,但是我以为it should be checked first。
论断
由于Eclipse编译器接收它,所以我偏向于以为这是1个JAVAC毛病,但是请留意,在标准圆里,有时比JAVAC更严松,而且曾经申报并修复了1些相似的毛病(JDK⑻0五七8九五,JDK⑻一七08四二,…)。
佳了闭于办法援用表白式为&Quot;Exact&Quot;的前提的学程便到这里便停止了,愿望趣模板源码网找到的这篇技巧文章能赞助到年夜野,更多技巧学程不妨在站内搜刮。