中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

Java中的構(gòu)造函數(shù)引用和方法引用

2018-12-21    來源:importnew

容器云強(qiáng)勢上線!快速搭建集群,上萬Linux鏡像隨意使用

JDK 8 見證了一個特殊特性的出現(xiàn):構(gòu)造函數(shù)引用和方法引用。在本文中, Adrian D. Finlay 探討了開發(fā)人員如何釋放構(gòu)造函數(shù)引用的真正潛力。

方法引用的一些背景

如果你還不知道 Java 構(gòu)造函數(shù)本身就是特殊的方法,那么閱讀方法引用的基本示例將對讀者有所幫助,通過了解這些內(nèi)容,可以了解構(gòu)造函數(shù)引用是什么。

「方法引用為已經(jīng)有名稱的方法提供易讀的 lambda 表達(dá)式!

「它們提供了一種無需執(zhí)行就可以引用方法的簡單方式!

以上引自《Java 8 編程參考官方教程(第 9 版)》,作者:Herbert Schildt

譯注:該書的第 8 版中文譯本名稱為:《Java 完全參考手冊(第 8 版)》,第 9 版中文譯本名稱為:《Java 8 編程參考官方教程(第 9 版)》

方法引用可以引用靜態(tài)方法和實(shí)例方法,兩者是通用的。方法引用是函數(shù)式接口的實(shí)例。雖然 Lambda 表達(dá)式允許你動態(tài)創(chuàng)建方法實(shí)現(xiàn),但通常情況下,一個方法最終會調(diào)用 Lambda 表達(dá)式中的另一個方法來完成我們想要完成的工作。更直接的方法是使用方法引用。當(dāng)你已經(jīng)有一個方法來實(shí)現(xiàn)這個函數(shù)式接口時,這是非常有用的。

讓我們看一個使用靜態(tài)方法及實(shí)例方法的示例。

//step #1 - Create a funnctional interface.
interface FuncInt {
    //contains one and only abstract method
    String answer(String x, boolean y);
}

//step #2 - Class providing method(s)that match FuncInt.answer()'s definition.
class Answer {
    static String ans_math_static(String x, Boolean y) {
        return "\"" + x + "\"" + "\t = \t" + y.toString().toUpperCase();
    }

    String ans_math_inst(String x, Boolean y) {
        return "\"" + x + "\"" + "\t = \t" + y.toString().toUpperCase();
    }
}

譯注:以上代碼的測試用例如下,因靜態(tài)方法與實(shí)例方法結(jié)果相同,僅以靜態(tài)方法為例。

Answer.ans_math_static("9 > 11 ?", false);
Answer.ans_math_static("987.6 < 1.1 ?", false);
Answer.ans_math_static("1 > 0.9 ?", true);
Answer.ans_math_static("T/F: Is Chengdu in Sichuan?", true);
Answer.ans_math_static("-1 % 0.2=0 ?", false);
Answer.ans_math_static("T/F: Does Dwyne Wade play for the Knicks?", false);

得到與原文舉例相同的輸出結(jié)果:

"9 > 11 ?"	 = 	FALSE
"987.6 < 1.1 ?"	 = 	FALSE
"1 > 0.9 ?"	 = 	TRUE
"T/F: Is Chengdu in Sichuan?"	 = 	TRUE
"-1 % 0.2=0 ?"	 = 	FALSE
"T/F: Does Dwyne Wade play for the Knicks?"	 = 	FALSE

另請參閱:關(guān)于var的所有內(nèi)容:局部變量類型推斷如何清除Java代碼冗余

使用方法引用的主要步驟有:

  1. 定義一個函數(shù)式接口
  2. 定義一個滿足函數(shù)式接口抽象方法要求的方法
  3. 使用對步驟2中定義的?(x :: y ) 方法引用實(shí)例化函數(shù)式接口的實(shí)例。
    譯注:靜態(tài)方法的方法引用格式為?類名 :: 方法名?;實(shí)例方法的方法引用格式為?對象實(shí)例名 :: 方法名?。
  4. 使用函數(shù)式接口實(shí)例調(diào)用方法:?Instance.AbstractMethod();

這提供了一種創(chuàng)建方法實(shí)現(xiàn)的可插拔方式。Lambda 表達(dá)式和方法引用為 Java 編程帶來了一個功能方面的提升。

另請參閱:你到底有多了解Java的注解?

構(gòu)造函數(shù)的方法引用

讓我們開始詳細(xì)討論吧。

構(gòu)造函數(shù)和其他方法一樣是方法。對嗎?錯。它們有點(diǎn)特殊,它們是對象初始化方法。盡管如此,它們?nèi)匀皇且粋方法,沒有什么能阻止我們像其他方法引用一樣創(chuàng)建構(gòu)造函數(shù)的方法引用。

//step #1 - Create a funnctional interface.
interface FuncInt {
    //contains one and only abstract method
    Automobile auto(String make, String model, short year);
}

//step #2 - Class providing method(s)that match FuncInt.answer()'s definition.
class Automobile {

    //Trunk Member Variables
    private String make;
    private String model;
    private short year;

    //Automobile Constructor
    public Automobile(String make, String model, short year) {
        this.make = make;
        this.model = model;
        this.year = year;
    }

    protected void what() {
        System.out.println("This Automobile is a" + year + " " + make + " " + model + ".");
    }
}

//Step #3 - Class making use of method reference
public class ConstrRef {

    static void createInstance() {
    }

    public static void main(String[] args) {
        System.out.println();

        //Remember, a Method Reference is an instance of a Functional Interface. Therefore....
        FuncInt auto = Automobile::new;//We really don't gain much from this example

        //Example #1
        Automobile honda = auto.auto("honda", "Accord", (short) 2006);
        honda.what();

        //Example #1
        Automobile bmw = auto.auto("BMW", "530i", (short) 2006);
        bmw.what();

        System.out.println();
    }
}

輸出結(jié)果

This Automobile is a2006 honda Accord.
This Automobile is a2006 BMW 530i.

說明

用戶應(yīng)該清楚的第一件事是這個基本示例沒有那么實(shí)用。這是一種相當(dāng)迂回的創(chuàng)建對象實(shí)例的方式。實(shí)際上,幾乎可以肯定,你不會經(jīng)歷所有這些麻煩來創(chuàng)建一個 Automobile 實(shí)例,但是為了概念的完整性,還是要提及。

使用構(gòu)造函數(shù)的方法引用的主要步驟有:

  1. 定義一個只有抽象方法的函數(shù)式接口,該方法的返回類型與你打算使用該對象進(jìn)行構(gòu)造函數(shù)引用的對象相同。
  2. 創(chuàng)建一個類,該類的構(gòu)造函數(shù)與函數(shù)式接口的抽象方法匹配。
  3. 使用對步驟 #2 中定義的構(gòu)造函數(shù)的方法引用,實(shí)例化函數(shù)式接口的實(shí)例。
    譯注:構(gòu)造函數(shù)的方法引用格式為?類名 :: new
  4. 在步驟 #2 中使用構(gòu)造函數(shù)引用實(shí)例化類的實(shí)例,例如?MyClass x = ConstructorReference.AbstractMethod (x, y, z…)

構(gòu)造函數(shù)引用與泛型一起使用的時候變得更有用。通過使用泛型工廠方法,可以創(chuàng)建各種類型的對象。

讓我們看一看。

//step #1 - Create a funnctional interface.
interface FuncInt<Ob, X, Y, Z> {
    //contains one and only abstract method
    Ob func(X make, Y model, Z year);
}

//step #2 - Create a Generic class providing a constructor compatible with FunInt.func()'s definition
class Automobile<X, Y, Z> {

    //Automobile Member Variables
    private X make;
    private Y model;
    private Z year;

    //Automobile Constructor
    public Automobile(X make, Y model, Z year) {
        this.make = make;
        this.model = model;
        this.year = year;
    }

    protected void what() {
        System.out.println("This Automobile is a " + year + " " + make + " " + model + ".");
    }
}

//step #3 - Create a Non-Generic class providing a constructor compatible with FunInt.func()'s definition
class Plane {

    //Automobile Member Variables
    private String make;
    private String model;
    private int year;

    //Plane Constructor
    public Plane(String make, String model, int year) {
        this.make = make;
        this.model = model;
        this.year = year;//Automatic unboxing
    }

    protected void what() {
        System.out.println("This Plane is a " + year + " " + make + " " + model + ".");
    }
}

//Step #3 - Class making use of method reference with generics
public class ConstrRefGen {

    //Here is where the magic happens
    static <Ob, X, Y, Z> Ob factory(FuncInt<Ob, X, Y, Z> obj, X p1, Y p2, Z p3) {
        return obj.func(p1, p2, p3);
    }

    public static void main(String[] args) {
        System.out.println();

        //Example #1
        FuncInt<Automobile<String, String, Integer>, String, String, Integer> auto_cons = Automobile<String, String, Integer>::new;
        Automobile<String, String, Integer> honda = factory(auto_cons, "Honda", "Accord", 2006);
        honda.what();

        //Example #2
        FuncInt<Plane, String, String, Integer> plane_cons = Plane::new;
        Plane cessna = factory(plane_cons, "Cessna", "Skyhawk", 172);
        cessna.what();

        System.out.println();
    }
}

輸出結(jié)果

This Automobile is a 2006 Honda Accord.
This Plane is a 172 Cessna Skyhawk.

另請參閱:Java 中的 struct :如何像專業(yè)人士一樣處理它們

說明

這里有很多東西需要消化。事實(shí)上,如果你以前從未深入研究過泛型,那么這些代碼看上去可能相當(dāng)晦澀。讓我們分解一下。

我們做的第一件事是創(chuàng)建一個通用的函數(shù)式接口。注意細(xì)節(jié)。我們有四個泛型類型參數(shù):Ob、X、Y、Z。

  • Ob 代表要引用其構(gòu)造函數(shù)的類。
  • X,Y,Z 代表該類的構(gòu)造函數(shù)的參數(shù)。

如果我們替換泛型方法占位符,抽象方法可能是這樣的:?SomeClass func (String make, String model, int year)。注意,由于我們使接口具有了泛型,所以可以指定任何返回類型或我們希望返回的類實(shí)例。這釋放了構(gòu)造函數(shù)引用的真正潛力。

接下來的兩個部分相對簡單,我們創(chuàng)建了相同的類,一個泛型類和一個非泛型類,以演示它們與在公共類中定義的工廠方法的互操作性。注意,這些類的構(gòu)造函數(shù)與?FuncInt.func()?的方法簽名是兼容的。

進(jìn)入公共類的文件。這個方法就是奇跡發(fā)生的地方。

//Here is where the magic happens
static <Ob, X, Y, Z> Ob factory(FuncInt<Ob, X, Y, Z> obj, X p1, Y p2, Z p3) {
    return obj.func(p1, p2, p3);
}

我們將該方法標(biāo)記為靜態(tài)的,所以我們可以不使用 ConstRefGen 實(shí)例,畢竟它是一個工廠方法。注意,factory 方法具有與函數(shù)式接口相同的泛型類型參數(shù)。注意,方法的返回類型是 Ob,它可以是由我們決定的任何類。當(dāng)然,X、Y、Z是 Ob 中方法的方法參數(shù)。請注意,該函數(shù)以 FuncInt 的一個實(shí)例作為參數(shù)(類類型和方法參數(shù)作為類型參數(shù)),同時也接受 Ob 類型的類作為方法的參數(shù)。

另請參閱:Reactor.js:用于響應(yīng)式編程的輕量級庫

在方法體中,它調(diào)用方法引用并將在?factory()?中傳遞的參數(shù)提供給它。

我們的第一個任務(wù)是創(chuàng)建一個符合?FuncInt<>?的方法引用。

這里我們分別引用 Automobile 類和 Plane 類的構(gòu)造函數(shù)。

我們的下一個任務(wù)是創(chuàng)建一個帶有方法引用的對象。

為此,我們調(diào)用?factory()?并將它需要的構(gòu)造函數(shù)引用以及?factory()?定義的有關(guān)構(gòu)造函數(shù)的參數(shù)提供給它。factory()?可以靈活地創(chuàng)建對各種方法的構(gòu)造函數(shù)引用,因?yàn)樗峭ㄓ玫摹R驗(yàn)?Plane 類和 Automobile 類的構(gòu)造函數(shù)匹配?FuncInt.func()?的方法簽名,所以它們可作為?FuncInt.func()?的方法引用使用。factory()?通過調(diào)用?obj.func(x,y,z)?返回類的一個實(shí)例,這是一個構(gòu)造函數(shù)方法引用,當(dāng)求值時,它將為你提供指定為其參數(shù)的類的一個實(shí)例。

斟酌這個問題一段時間,會發(fā)現(xiàn)它是Java的一個非常有用的補(bǔ)充?;)

原文鏈接: jaxenter 翻譯: ImportNew.com - Mr.Dcheng
譯文鏈接: http://www.importnew.com/30974.html
[ 轉(zhuǎn)載請保留原文出處、譯者和譯文鏈接。]

關(guān)于作者: Mr.Dcheng

查看Mr.Dcheng的更多文章 >>

標(biāo)簽: 代碼

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:每周10道Java面試題:面向?qū)ο? 類加載器, JDBC, Spring 基礎(chǔ)概念

下一篇:Spring源碼探究:容器