双冒号 ::的作用是更简洁的替换 lambda表达式的一般形式 - > 。
首先要明白什么时候能写 lambda 表达式 ?
lambda作用于函数式接口,函数式接口指的是 只有一个抽象方法的接口(当然,该接口可以拥有多个默认方法和静态方法,不会影响它是函数式接口的事实),当我们需要重写函数式接口时,我们就可以使用lambda表达式的形式,来替换接口的匿名内部类的写法。
现有以下几种写法(类名::类的实例方法 或 类名::类的静态方法 或 对象::对象的实例方法 或 类名::new):
一 、(类名::类的实例方法 )有以下几种情况
1.此时test方法参数为B 返回值为void,双冒号左边为B 右边print方法的返回值是void
2.此时test方法参数为B 返回值为int,双冒号左边为B 右边print方法的返回值是int
3.此时test方法有两个参数都是B类型 返回值为int,双冒号左边为B 右边print方法的参数为B类型 返回值是int
4.我将test方法参数变更为三个B类型,同时print方法参数变更为两个B类型
对于上图和下图 细心的我发现了一个规律:只要参数 b ,b2,b3.... 和 b.方法名(b2,b3.....) 是对应的 我就能写成 B::方法的形式 。
接下来我开始使用泛型:
5.此时我使用泛型T 作为test方法的参数,第一种情况将T替换为类B,则双冒号左边要写类B 右边print方法返回值和test方法返回值一样都是int,第二种情况将T替换为类String,则双冒号左边要写类String 右边的hashCode方法返回值也是int,也就是说只要双冒号右边的方法的返回值 与 test方法返回值一样 那么就都符合写法要求。
二、(类名::类的静态方法)和 (对象::对象的实例方法)
这两种写法其实原理是一样的:目的是为了替换方法体
看以下例子就明白了:
通过上面两图总结规律:无论是 B::静态方法bTest 还是 B对象::实例方法bTest 。其中test方法的返回值和参数列表 与 bTest方法的返回值和参数列表都一致。你可以理解为 Test方法被bTest方法完全替换 或 bTest方法是test方法的实现
三、(类名::new)
对于上图的结论是:test方法的参数为(String s) 且返回值是类B,那么只要类B只要有一个构造方法的参数是(String s) 那么就可以写成 A a=B::new 的 形式 。同理test方法的参数为(String s,String y) 返回值是类B,那么只要类B有一个构造方法的参数是(String s,String y)就可以了。
读者可以尝试修改代码来验证我的结论:
欢迎大佬批评指正!



