1. 程式人生 > >java8 新特性值方法引用(::)

java8 新特性值方法引用(::)

java8中的方法引用(雙冒號)::是類似於C++的域運算子,獲取方法使用的。

使用場景:cars.forEach( Car::repair );

1、構造方法引用(Class::new):

      相當於建立物件;如果函式式介面方法有引數,會匹配具體有參構造方法。

2、靜態方法引用(Class::static_method):

       相當於ClassName.staticMethod(),如果有引數會把引數當方法的實參。

3、特定類任意任意物件方法引用(Class::method):

      相當於new ClassName().method(),會把第一個引數當作類物件,來呼叫特定類的任意物件方法,其他引數當作方法的引數。

4、特定物件方法引用(instance::method):

      相當於instance.method(),如果有引數,引數就是方法的引數。

特點:

忽略名稱:介面與介面抽象方法;

限制類型:具體物件引用方法的返回值型別和方法引數型別與介面抽象方法的返回值型別與引數型別一致。

https://www.cnblogs.com/softidea/p/5280921.html

構造方法引用:

public class T02 {
    public static void main(String[] args) {
        A a = C::new;//引用C的無參構造
        a.test()
        B b = C::new;//引用C的String類行的有參構造
	b.test("this is B interface test method...");
    }
}

interface A {
 void test();
}

interface B{
    void test(String s);
}

class C {
    
    public C(){
        System.out.println("--empty--constructor= ");
    }
    public C(String s){
        this.a=s;
        System.out.println("--not empty--constructor= "+s);
    }

}

靜態方法引用:

public class T02 {
    public static void main(String[] args) {
        //這裡的C::accept方法對應的是Consumer函式介面中的accept方法,返回值型別和引數型別一致,
        //實際就是對lambda表示式的簡化,將lambda的語句體邏輯通過某個類的方法執行
        Arrays.asList("a","c","b").forEach(C::accept);//實際對應的就是下面的匿名內部類方法。
        //仔細觀察就是省略了Consumer和accept等操作,直接實現Consumer.accept方法
        Arrays.asList("a","c","b").forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                C.accept(s);
            }
        });
    }
}

class C {
   
    public static void accept(String s) {
        System.out.println("this is static = "+s);
    }
}

特定類任意任意物件方法引用:

public class T02 {
    public static void main(String[] args) {
        //特定類的任意物件方法引用實際就是特定物件的方法引用的無參表現
        //非靜態方法引用:
        //特定類的任意物件方法引用:只有一個引數且正好是C
        //特定物件的方法引用:如果第一個引數正好是C,第二個引數和accept方法的引數型別一致,那麼也可以寫作:C::accept,如果第一個引數不是C,那麼只好自己new一個C來呼叫accept
        Arrays.asList(new C(),new C(),new C()).forEach(C::accept);
    }
}

class C {
    public void accept(String s) {
        System.out.println("test");
    }
}

特定物件方法引用:

public class T02 {
    public static void main(String[] args) {
        Arrays.asList("a","b","c").forEach(new C()::accept);//因為只有一個引數String型別,不具備C型別,所以只能自己new C()來呼叫。
        //如果正好有兩個引數,一個是C型別,一個是String型別,那麼可以直接寫做:C::accept
        //第一個C型別的引數會充當特定的物件,第二個String會作為accept的引數。等同於 c.accept
        //非靜態方法引用:
        //特定類的任意物件方法引用:只有一個引數且正好是C
        //特定物件的方法引用:如果第一個引數正好是C,第二個引數和accept方法的引數型別一致,那麼也可以寫作:C::accept,如果第一個引數不是C,那麼只好自己new一個C來呼叫accept(string);
    }
}

class C {
    public void accept(String s) {
        System.out.println("test s = " + s);
    }
}