java 双冒号用法

  

 JDK8中有双冒号的用法,形如Class::methodname,符号左边是调用方法所处的类名,符号右边是调用的静态方法。简单的说,就是逐一传入参数值到某个类的静态方法并调用该静态方法。

以前的方式

public static void  printValue(String str){
    System.out.println("print value : "+str);
}
public static void main(String[] args) {
    List list = Arrays.asList("a","b","c","d");
    for (String a: list) {
        Test.printValue(a);
    }
    System.out.println("===============================");
    //下面的for each循环和上面的循环是等价的
    list.forEach(s->{
        Test.printValue(s);
    });
}
print value : a
print value : b
print value : c
print value : d
===============================
print value : a
print value : b
print value : c
print value : d

现在使用双冒号的方式

public static void print(String str) {
    System.out.println("print vlistue : " + str);
}
public static void main(String[] args) {
    List list = Arrays.asList("a", "b", "c", "d");
    list.forEach(Test::print);//遍历集合的元素,并逐一传入调用的静态方法中,实现各元素的打印
    System.out.println("=======================================");

    //下面的方法和上面的方法是等价的
    Consumer methodParam = Test::print; //定位到调用方法的参数位置
    list.forEach(s -> methodParam.accept(s));//遍历传送元素-定位处逐一接收传送过来的各元素,并打印
}
print vlistue : a
print vlistue : b
print vlistue : c
print vlistue : d
=======================================
print vlistue : a
print vlistue : b
print vlistue : c
print vlistue : d

有的时候,我们还会看到Object::的用法

其实用法也差不多,只不过Class::function的形式中function是属于Class的,可以是静态方法也可以是非静态方法。而Object::的形式中funtion是属于这个对象的,可以是静态方法也可以是非静态方法。Object::中比较特殊的代表就是this::的用法了,指向当前对象。

下面,来看看几种用法示例。

1)System.out::println

public static void main(String[] args) {
    String[] array = {"aa", "xx", "ss"};
    List list = Arrays.asList(array);
    //Java 7
    for(String s:list){
        System.out.println(s);
    }
    //Java 8
    list.forEach(System.out::println);
}

说明:System.out是一个对象,而且是一个PrintStream类型的实例。println是PrintStream类中的一个非静态方法。

System.out.println()的真正含义

out是System类中的一个静态属性,默认值为null,类型为PrintStream。System.out的实例化是通过System类中的initializeSystemClass方法完成的,在虚拟机加载的时候完成初始化。

2)instance::print

public class Test {
    public static void main(String[] args) {
        List list = Arrays.asList("aa", "xx", "ss");
        //形如 instanceRef::methodName
        list.forEach(new Demo()::print);
    }
}
class Demo{
    public void print(String content){
        System.out.println(content);//aa xx ss
    }
}

3)super::print

public class Test extends Demo{
    public void invokePrint(){
        List list = Arrays.asList("aa", "xx", "ss");
        //形如 instanceRef::methodName
        list.forEach(super::print);
    }
    public static void main(String[] args) {
        new Test().invokePrint();
    }
}
class Demo{
    public void print(String content){
        System.out.println(content);//aa xx ss
    }
}

 4)this::print

public class Test extends Demo{
    public void invokePrint(){
        List list = Arrays.asList("aa", "xx", "ss");
        //形如 instanceRef::methodName
//        list.forEach(super::print);
        list.forEach(this::print);
    }
    @Override
    public void print(String content){
        System.out.println("【子类-重写】"+content);
    }
    public static void main(String[] args) {
        new Test().invokePrint();
    }
}
class Demo{
    public void print(String content){
        System.out.println(content);
    }
}

5)类无参构造器语法-Class::new

public class Test {
    public void test() {
        InterfaceTest com =  Test::new;//这里并不是真正的实现,而是绑定new Test操作(关联)到接口方法
        Test bean = com.create();//调用create方法时才真正触发new Test()操作
        System.out.println(bean);
    }
    public static void main(String[] args) {
        new Test().test();
    }
}
interface InterfaceTest{
    Test create();
}

说明:通过idea的标记提示好像Test实现了InterfaceTest,但其实并没有真正实现InterfaceTest!

6)类有参构造器语法-Class::new

public class Test {
    private String name;
    Test(String name){
        this.name = name;
    }
    Test(){
    }
    public void test() {
        InterfaceTest com =  Test::new;//这里并不是真正的实现,而是绑定new Test操作(关联)到接口方法
        Test bean = com.create("hello world");//调用create方法时才真正触发new Test("hello world")操作
        System.out.println(bean);
        System.out.println(bean.name);
    }
    public static void main(String[] args) {
        new Test().test();
    }
}
interface InterfaceTest{
    Test create(String name);
}
Test@161cd475
hello world

7)数组构造器语法-Test[]::new

借用jdk自带的java.util.function.Function接口实现

public class Test {
    public static void main(String[] args) {
        Function function = Test[]::new;//关联操作到接口方法
        Test[] array = function.apply(3);//真正调用,创建大小为3的数组

        for (Test e : array) {
            System.out.println(e);//输出3个空对象(null)
        }
    }
}

使用自定义接口实现(需要使用@FunctionalInterface注解标记)

public class Test {
    public static void main(String[] args) {
        Interface  function = Test[]::new;
        Test[] array = function.apply(3);

        for(Test e:array){
            System.out.println(e);
        }
    }
}
@FunctionalInterface
interface Interface{
    T apply(A a);
}

8)ArrayList::new

可以这么操作

public static void main(String[] args) {
    List list = new ArrayList<>();
    list.add("alpha");
    list.add("beta");
    list = list.stream().map(s -> s.toUpperCase()).collect(Collectors.toList());
    System.out.println(list);//[ALPHA, BETA]
}

也可以这么操作

public static void main(String[] args) {
    List list = new ArrayList<>();
    list.add("alpha");
    list.add("beta");
    //String::toUpperCase表示String的非静态方法被各个元素调用
    list = list.stream().map(String::toUpperCase).collect(Collectors.toCollection(ArrayList::new));
    System.out.println(list);//[ALPHA, BETA]
}

还可以这么操作

public static void main(String[] args) {
    List list = new ArrayList<>();
    list.add("alpha");
    list.add("beta");
    //调用Strings的toUpperCase静态方法
    list = list.stream().map(Strings::toUpperCase).collect(Collectors.toCollection(ArrayList::new));
    System.out.println(list);//[ALPHA, BETA]
}

 

你可能感兴趣的:(java 双冒号用法)