Java 如何使用方法引用调用参数化方法

Java 如何使用方法引用调用参数化方法,java,lambda,java-8,method-reference,Java,Lambda,Java 8,Method Reference,考虑下面的代码 interface TestInter { public void abc(); } class DemoStatic { public static void testStatic(String abc) { System.out.println(abc); } public void runTest () { // Using lambda expression. String str

考虑下面的代码

interface TestInter {
    public void abc();
}


class DemoStatic {

    public static void testStatic(String abc) {
        System.out.println(abc);
    }

    public void runTest () {

        // Using lambda expression.
        String str = "demo string" ;
        TestInter demo1 = () -> DemoStatic.testStatic(str);
        demo1.abc();

        // Using method reference.
        TestInter demo2 = DemoStatic::testStatic; // This line is not compiling.
        demo2.abc();
    }
}
我们可以调用
testStatic
方法作为
TestInter
接口的
abc()
实现的主体,如果
testStaic()
方法的参数将被消除,如中所述


但是在这种情况下,我们如何为参数化方法
testStatic
编写方法引用?

您的函数接口
TestInter
没有相应的
testStatic(String)
方法签名。如果要使用
符号引用
testStatic()
,则应添加参数:

interface TestInter2 {
    public void abc(String abc);
}

public void runTest () {
    TestInter2 demo2 = DemoStatic::testStatic;
    demo2.abc(str);
}
根据,有四种方法参考:

我为0、1和2参数准备了3个接口。然后我们有3个静态方法和3个实例方法:

interface F0 {
    void f0();
}
interface F1 {
    void f1(MetRef i1);
}
interface F2 {
    void f2(MetRef i1, MetRef i2);
}

public class MetRef {
    public static void stat0() {;}
    public static void stat1(MetRef a) {;}
    public static void stat2(MetRef a, MetRef b) {;}

    public void inst0() {;}
    public void inst1(MetRef a) {;}
    public void inst2(MetRef a, MetRef b) {;}
}
现在看看每种方法如何在各种组合中用作方法引用,将它们与上表进行比较。请参阅不同的方法引用类型,并注意参数的来源

public class Test {
    public static void main(String[] args) {
        final MetRef mr = new MetRef();

        final F0 mr01 = MetRef::stat0; // 1: f0() ~ MetRef.stat0() 
        final F0 mr02 = mr::inst0;     // 2: f0() ~ mr.inst0()
        final F0 mr04 = MetRef::new;   // 4: f0() ~ new MetRef()

        final F1 mr11 = MetRef::stat1; // 1: f1(i1) ~ MetRef.stat1(i1)
        final F1 mr12 = mr::inst1;     // 2: f1(i1) ~ mr.inst1(i1)
        final F1 mr13 = MetRef::inst0; // 3: f1(i1) ~ i1.inst0()       <== NOTICE!

        final F2 mr21 = MetRef::stat2; // 1: f2(i1, i2) ~ MetRef.stat2(i1, i2)
        final F2 mr22 = mr::inst2;     // 2: f2(i1, i2) ~ mr.inst2(i1, i2)
        final F2 mr23 = MetRef::inst1; // 3: f2(i1, i2) ~ i1.inst1(i2) <== NOTICE!
    }
}
公共类测试{
公共静态void main(字符串[]args){
最终MetRef mr=新MetRef();
final F0 mr01=MetRef::stat0;//1:F0()~MetRef.stat0()
final F0 mr02=mr::inst0;//2:F0()~mr.inst0()
final F0 mr04=MetRef::new;//4:F0()~new MetRef()
最终的F1 mr11=MetRef::stat1;//1:F1(i1)~MetRef.stat1(i1)
最终F1 mr12=mr::inst1;//2:F1(i1)~mr.inst1(i1)

final F1 mr13=MetRef::inst0;//3:F1(i1)~i1.inst0()你不能-它不适合功能接口。你希望
abc
参数的值在
testStatic
中是什么?在你传入的lambda表达式中
str
,这很有意义。你可以在两个不同的方法签名之间创建一个适配器(创建两个函数接口,以及一个适配器,该适配器基于另一个和一个额外参数调用其中一个)。他们没有为此设计语法。而且似乎不值得为其增加语言复杂性。如果您希望能够键入类似
DemoStatic::testStatic(str)的内容
,这实际上只比lambda表达式少几个按键。没有包装器方法/lambda,Java不支持。记住,lambda表达式与方法引用不同。@kisharsechagajjar:这是一个非常好的函数接口,但必须由具有适当签名的方法实现。