java8之方法引用

方法引用是与函数式接口配套使用的,其标志符号为双冒号::
方法引用是一种很有用的语法,可以直接引用已有类或对象的方法或构造器。与lambda配合使用,可以使语言的构造更紧凑简洁,减少冗余代码。
(1)构造方法引用:

public class Test1 {
    public static void main(String[] args) {
            Supplier<Test1> supplier =  Test1::new;
    }
}

其实上面这段代码,与下面的代码是相类似的,只不过更加地简洁紧凑。

public class Test1 {
    public static void main(String[] args) {
        Supplier<Test1> supplier =  ()->new Test1();
    }
}

(2)静态方法引用:
该引用是把静态方法作为接口实现方法的实现,不用繁琐地为接口实现该静态方法的功能,精简了代码,提供了另一种语法习惯。
例子如下:

public class Test1 {
    public static Test1 a(){
        return null;
    }
    public static void main(String[] args) {
        Supplier<Test1> supplier =  Test1::a;
    }
}

有心人会发现,supplier接口和a接口都是无参数的,这并不是说,静态方法引用需要无参数,而是静态方法的入参类型需要和需要实现的接口方法保持一致,包括返回值类型。比如说需要实现的接口入参是一个int类型,返回值为int类型,那么使用的静态方法的入参类型和返回值类型就不能是String类型的。其实上面这段代码相当于:

public class Test1 {
    public static Test1 a(){
        return null;
    }
    public static void main(String[] args) {
        Supplier<Test1> supplier =  ()->a();
    }
}

(3)特定对象的方法引用
这个需要先有对象,才能使用。因为普通方法是对象的一部分,这和静态方法是类(或者接口等)的一部分的情况不太一样。所以,首先先弄个对象,
然后就能像静态方法引用一样了,只不过是把类换成了对象,表明该对象的某某方法。
例子如下:

public class Test1 {
    public Test1 a(){
        return null;
    }
    public static void main(String[] args) {
        Supplier<Test1> supplier =  new Test1()::a;
    }
}

相当于下面这段代码:

public class Test1 {
    public Test1 a(){
        return null;
    }
    public static void main(String[] args) {
        //会不会把new Test1()存起来呢?
        //没反编译过,没扫字节码,不太清楚
        //讲道理,应该是会的,因为要是我我也会存
        Supplier<Test1> supplier =  ()->(new Test1().a());
    }
}

(4)引用类型对象的实例方法
这个是引用接口第一个参数的方法,因此接口的第一个参数需要具有该方法,而且,剩下的参数与方法的参数保持一致,也就是说,接口方法的参数,要比引用方法的参数多了第一个,其它部分相同,而且第一个参数要是该引用方法的所在类型的或其父类。
例子如下:
例子1:

public  class Test1 {
    public void a(){
    }
    public static void main(String[] args) {
        MyInter m = Test1::a;
    }
}
@FunctionalInterface
interface MyInter {
    //入参参数比Test1的a方法多一个,且Test1::a的Test1是该入参类型Test1相同
    public void d(Test1 d);
}

例子2:

public  class Test1 {
    public void a(Integer param1,int param2){
    }
    public static void main(String[] args) {
        MyInter m = Test1::a;
    }
}
@FunctionalInterface
interface MyInter {
    //该接口参数比上述的a方法参数数量多一个,除去第一个,其它类型一致(可兼容,如可以一个int,一个Integer)
    //且Test1::a的Test1是该入参类型Test1相同
    public void d(Test1 d,int param1,int param2);
}

例子3:

public  class Test1 {
    public void a(Integer param1,int param2){
    }
    public static void main(String[] args) {
        MyInter m = Test1::a;
    }
}
class Test2 extends Test1 {
}
@FunctionalInterface
interface MyInter {
    //该接口参数比上述的a方法参数数量多一个,除去第一个,其它类型一致(可兼容,如可以一个int,一个Integer)
    //且Test1::a的Test1是该入参类型Test2的子类(不可颠倒)
    public void d(Test2 d,int param1,int param2);
}

其实该引用的实质就是第一个参数调用了引用方法,如同下述的代码

public  class Test1 {
    public void a(Integer param1,int param2){
    }
    public static void main(String[] args) {
        MyInter m = (j,k,l)->j.a(k, l);
    }
}
@FunctionalInterface
interface MyInter {
    public void d(Test1 d,int param1,int param2);
}

用匿名内部类表示就是:

public  class Test1 {
    public void a(Integer param1,int param2){
    }
    public static void main(String[] args) {
        MyInter m = new MyInter() {
            @Override
            public void d(Test1 d, int param1, int param2) {
                d.a(param1, param2);
            }
        };
    }
}
@FunctionalInterface
interface MyInter {
    public void d(Test1 d,int param1,int param2);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值