成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java基礎(chǔ)-接口、lambda表達(dá)式

wmui / 1542人閱讀

摘要:表達(dá)式會(huì)復(fù)制一份自由變量的值,對(duì)象的話就是復(fù)制一個(gè)引用,因此表達(dá)式離開了原作用域也能正常使用自由變量。不過表達(dá)式對(duì)自由變量是有要求的,自由變量必須是不可變的,原因是并發(fā)執(zhí)行時(shí)不安全。

Java 8新增的lambda表達(dá)式毫無疑問是令人非常激動(dòng)的,從此我們可以非常簡(jiǎn)潔的定義和使用代碼塊而不是用繁瑣的匿名內(nèi)部類來實(shí)現(xiàn)。而接口是lambda表達(dá)式的基礎(chǔ),要理解lambda表達(dá)式就要先理解接口的概念。

接口

Java中接口是對(duì)類行為的抽象。似乎繼承也能做到這件事,它們的區(qū)別在于Java中類只能有一個(gè)父類,而接口是可以實(shí)現(xiàn)多個(gè)的。所以接口更傾向于類的一部分抽象,也就是行為的抽象,而不是類本身的抽象。

語法

要定義一個(gè)接口很簡(jiǎn)單,使用關(guān)鍵字interface后面再跟上接口名稱就可以了。類可以用implements關(guān)鍵字來實(shí)現(xiàn)接口。

public interface A {
    void test();
}

接口不允許有實(shí)例域,但可以有常量

接口中的域都會(huì)自動(dòng)聲明為public static final

接口中的方法都會(huì)自動(dòng)聲明為public

接口中可以聲明抽象方法,Java 8以后還可以聲明靜態(tài)方法和默認(rèn)方法

// Java 8版本
public interface A {
    //常量
    String AUTHOR = "Yuicon";
    //抽象方法
    void test();
    //默認(rèn)方法
    default void testDefault(){}
    //靜態(tài)方法
    static void testStatic(){}
}
默認(rèn)方法的沖突

如果一個(gè)類實(shí)現(xiàn)的接口中有簽名相同的默認(rèn)方法,那么就會(huì)有沖突的問題。在Java中解決這個(gè)問題有一些明確的規(guī)則:

在超類中已有同簽名的方法,就會(huì)忽略接口中的默認(rèn)方法,也就是超類優(yōu)先

接口中默認(rèn)方法和另一個(gè)默認(rèn)方法或者抽象方法沖突的,必須要覆蓋這個(gè)方法

lambda表達(dá)式

lambda表達(dá)式是一個(gè)可傳遞的代碼塊,可以在以后執(zhí)行一次或多次。之所以會(huì)有這么一個(gè)特性,是因?yàn)樵仍贘ava中傳遞一個(gè)代碼塊是非常繁瑣的一件事情,必須要構(gòu)建一個(gè)對(duì)象。比如常用的Runnable接口:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("我好麻煩");
    }
};

lambda版本就非常簡(jiǎn)潔:

Runnable runnable = () -> System.out.println("我很簡(jiǎn)潔");

是的,lambda版本只要一行就完成了任務(wù)。

語法

在我看來lambda表達(dá)式是一種語法糖,它提供了一種簡(jiǎn)潔、易懂的方式來實(shí)現(xiàn)只有一個(gè)抽象方法的接口。關(guān)鍵詞是只有一個(gè)抽象方法的接口,比如這樣一個(gè)接口:

@FunctionalInterface
public interface A {
    void test();
}

A a = () -> System.out.println("test");
a.test();

其中@FunctionalInterface注解是用來標(biāo)記接口為函數(shù)式接口,去掉也不會(huì)影響功能,添加了這個(gè)注解后編譯器會(huì)檢查接口內(nèi)是否只有一個(gè)抽象方法。

lambda表達(dá)式主要有以下要素:

參數(shù)

箭頭 ->

方法體

自由變量

參數(shù)

lambda表達(dá)式的參數(shù)和普通方法的參數(shù)并無太大區(qū)別,主要的區(qū)別點(diǎn)有:

如果參數(shù)的類型可以被編譯器推導(dǎo)出來,那么可以省略參數(shù)類型

如果參數(shù)的類型可以被編譯器推導(dǎo)出來,而且只有一個(gè)參數(shù),那么就可以省略括號(hào)

Consumer consumer = s -> System.out.println(s); 
方法體

lambda表達(dá)式的方法體內(nèi)只有一條語句的時(shí)候,可以不加大括號(hào)且無需指定返回值,編譯器會(huì)自動(dòng)推導(dǎo)。方法體內(nèi)有多條語句的時(shí)候就需要加大括號(hào)并手動(dòng)指定返回值,不過lambda表達(dá)式是沒有自己的作用域的,這點(diǎn)需要注意。

Supplier supplier = () -> {
    String s = "test";
    return s;
};
自由變量

自由變量是指非參數(shù)而且不在方法體內(nèi)定義的變量,我們來看一個(gè)例子:

    public static void main(String[] args) {
        String test = "test";
        A a = () -> System.out.println(test);
        a.test();
    }

例子中的變量test就是一個(gè)自由變量,代碼塊a引用了外部方法的變量,這就是一個(gè)閉包了。lambda表達(dá)式會(huì)復(fù)制一份自由變量的值,對(duì)象的話就是復(fù)制一個(gè)引用,因此lambda表達(dá)式離開了原作用域也能正常使用自由變量。不過lambda表達(dá)式對(duì)自由變量是有要求的,自由變量必須是不可變的,原因是并發(fā)執(zhí)行時(shí)不安全。以下代碼是錯(cuò)誤的:

for (int i = 0; i < 9; i++) {
    // error
    A a = () -> System.out.println(i);
}
方法引用

方法引用是語法糖的語法糖,顧名思義方法引用是引用已有方法的一個(gè)特性。它的形式如下:

@FunctionalInterface
public interface A {

    void test(String s);

}

A a = System.out::println;
a.test("test");

之所以說方法引用是語法糖的語法糖是因?yàn)?b>A a = System.out::println;完全等價(jià)于A a = s -> System.out.println(s);,方法引用有5種情況:

object::instanceMethod

this::instanceMethod

super::instanceMethod // 超類方法

Class::staticMethod

Class::instanceMethod

前4種情況和lambda表達(dá)式是完全等價(jià)的,第5種情況比較特殊,第一個(gè)參數(shù)會(huì)成為方法的目標(biāo)。比如String::compareToIgnoreCase等同于 (x, y)-> x.compareToIgnoreCase(y)

構(gòu)造器引用

構(gòu)造器引用是引用對(duì)象的構(gòu)造器,用的是特殊的方法名new,使用形式為Object::new,使用方法和方法引用差不多。

常用函數(shù)式接口

JDK已經(jīng)提供了常用的函數(shù)式接口基本上是不需要自己寫函數(shù)式接口的。

后記

一周一篇是不可能一周一篇的,人懶起來就和咸魚一樣根本不會(huì)動(dòng)彈。還好人是會(huì)變通的,上周少了這周補(bǔ)上不就行了!Java被人詬病繁瑣不是一天兩天了,在各種新生編程語言的追趕下Java也要加快自己的演進(jìn)了,更改發(fā)布周期就是一個(gè)很好的信號(hào)。

參考資料:
《Java核心技術(shù) 卷1》

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/76841.html

相關(guān)文章

  • 【從基礎(chǔ)學(xué) Java接口與內(nèi)部類

    摘要:即接口是用來描述對(duì)象具有的某種功能,而不關(guān)心具體實(shí)現(xiàn)?;蛘哒f,接口好比服務(wù)商指定的標(biāo)準(zhǔn),由代加工工廠遵守來生產(chǎn)。內(nèi)部類允許在類中定義其它類,這種定義在類中的類叫做嵌套類。局部類是聲明,匿名類是表達(dá)式。匿名類當(dāng)需要聲明字段或其它方法時(shí)。 接口 在繼承那篇博文里,我們已經(jīng)簡(jiǎn)單了解了 Java 接口的概念。即:接口是用來描述對(duì)象具有的某種「功能」,而不關(guān)心具體實(shí)現(xiàn)?;蛘哒f,接口好比服務(wù)商指定...

    NeverSayNever 評(píng)論0 收藏0
  • Java8新特性總覽

    摘要:新特性總覽標(biāo)簽本文主要介紹的新特性,包括表達(dá)式方法引用流默認(rèn)方法組合式異步編程新的時(shí)間,等等各個(gè)方面。還有對(duì)應(yīng)的和類型的函數(shù)連接字符串廣義的歸約匯總起始值,映射方法,二元結(jié)合二元結(jié)合。使用并行流時(shí)要注意避免共享可變狀態(tài)。 Java8新特性總覽 標(biāo)簽: java [TOC] 本文主要介紹 Java 8 的新特性,包括 Lambda 表達(dá)式、方法引用、流(Stream API)、默認(rèn)方...

    mayaohua 評(píng)論0 收藏0
  • 深入淺出 Java 8 Lambda 達(dá)式

    摘要:在支持一類函數(shù)的語言中,表達(dá)式的類型將是函數(shù)。匿名函數(shù)的返回類型與該主體表達(dá)式一致如果表達(dá)式的主體包含一條以上語句,則表達(dá)式必須包含在花括號(hào)中形成代碼塊。注意,使用表達(dá)式的方法不止一種。 摘要:此篇文章主要介紹 Java8 Lambda 表達(dá)式產(chǎn)生的背景和用法,以及 Lambda 表達(dá)式與匿名類的不同等。本文系 OneAPM 工程師編譯整理。 Java 是一流的面向?qū)ο笳Z言,除了部分簡(jiǎn)...

    wdzgege 評(píng)論0 收藏0
  • Java 8 新特性之Lambda達(dá)式

    摘要:概述簡(jiǎn)介是一個(gè)匿名函數(shù),我們可以把表達(dá)式理解為是一段可以傳遞的代碼將代碼像數(shù)據(jù)一樣進(jìn)行傳遞。作為一種更緊湊的代碼風(fēng)格,使的語言表達(dá)能力得到了提升。任何滿足單一抽象方法法則的接口,都會(huì)被自動(dòng)視為函數(shù)接口。 1. 概述 1.1 簡(jiǎn)介 Lambda 是一個(gè)匿名函數(shù),我們可以把 Lambda 表達(dá)式理解為是一段可以傳遞的代碼(將代碼像數(shù)據(jù)一樣進(jìn)行傳遞)。可以寫出更簡(jiǎn)潔、更靈活的代碼。作為一種更...

    Ververica 評(píng)論0 收藏0
  • Java 8 vs. Scala(一): Lambda達(dá)式

    摘要:編程語言將函數(shù)作為一等公民,函數(shù)可以被作為參數(shù)或者返回值傳遞,因?yàn)樗灰暈閷?duì)象。是表示已注釋接口是函數(shù)接口的注釋。如果一個(gè)函數(shù)有一個(gè)或多個(gè)參數(shù)并且有返回值呢為了解決這個(gè)問題,提供了一系列通用函數(shù)接口,在包里。 【編者按】雖然 Java 深得大量開發(fā)者喜愛,但是對(duì)比其他現(xiàn)代編程語言,其語法確實(shí)略顯冗長(zhǎng)。但是通過 Java8,直接利用 lambda 表達(dá)式就能編寫出既可讀又簡(jiǎn)潔的代碼。作者...

    yuanxin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<