Java行為參數化(一)

一.什么是行為參數化呢 說白了就是將一段行為當作參數傳入一個方法中唄,那么這段行為是什么呢?

答:那也是一個方法咯。

Java在1.8版本引入了行為參數化的概念,首先,我們先看一小段代碼

public class test { public static void main(String[] args){ Consumer consumer = new Consumer() { @Override public void accept(String s) { System.out.println(s); } };

    show(consumer ,"hello world");
}public static void show(Consumer<String> consumer,String text){consumer.accept(text);
}
復制代碼

} 輸出結果當然是:hello world 啦。

可是你想這有什么呢?不就是寫了一個Consumer接口,然后寫一個匿名類重寫他的accept方法,然后帶入Consumer到show方法調用它咩?Java沒更新前也可以這樣啊,只不過是傳參了一個對象,然后在方法內調用了對象的方法。

那么我們再來看看下面這段代碼,看看它和上面的代碼有什么不同:

public class test { public static void main(String[] args){ /Consumer consumer = new Consumer() { @Override public void accept(String s) { System.out.println(s); } };/

    show(System.out::println ,"hello world");
}public static void show(Consumer<String> consumer,String text){consumer.accept(text);
}
復制代碼

} 注意!代碼中3到8行已經注釋了哦。

現在看看:show方法接受一個Consumer對象和字符串,然后調用對象的accept方法,這里都沒變;可是著方法中調用show方法的時候傳遞的第一個參數不再是Consumer對象了,而是System.out::println,而這是什么意思呢?

System.out::println 是方法引用,方法引用的格式就是:類名::方法名 或者 對象名::成員方法名

我們都知道,在方法重寫和重載中我們是怎么做的呢?在子類中寫一個和主類中被重寫方法方法名相同、參數類型、順序相同的方法,那jdk是根據什么來判斷是否是重寫或者重載呢?沒錯,就是靠函數簽名來判斷的,就比如上面代碼中的show方法,它的函數簽名就是:名為show、接受兩個參數并且第一個參數是Consumer類型、第二個參數是String類型的函數,如果返回類型相同,則是重寫;否則是重載。Java根據你的方法引用來確定你的方法簽名和返回類型,如果和形參中Consumer對象中的方法相同的話,就可以使用。

那么我們回到代碼中去,我們在主方法中調用show方法時傳入的第一個參數就是一個:無返回值,接受一個泛型參數的方法簽名的方法引用。

你也可以傳入其他方法進去,只要方法簽一致就可以啦。就像下面一樣:

public class test { public static void main(String[] args){ /Consumer consumer = new Consumer() { @Override public void accept(String s) { System.out.println(s); } };/ test one = new test();

    show(one::otherMethod ,"hello world");
}public void otherMethod(T t){int i = 0;System.out.println(i + t.toString());
}public static void show(Consumer<String> consumer,String text){consumer.accept(text);
}
復制代碼

} 結果是輸出:0hello world

你也可以將show方法的第二個參數換成一個集合,然后在第一個參數中傳入其他方法引用來對集合進行操作哦。

在上面我們說到在帶哦用show方法時傳入的方法引用的方法簽名、返回類型要和Consumer對象中方法的一致,那么這個Consumer到底是什么呢?它的內部只有一個方法嗎?如果有多個方法的話怎樣根據傳入的方法引用和他的眾多方法比較呢?

答:Consumer其實是一個接口,一個函數式接口,話不多說,直接上源碼

package java.util.function;

import java.util.Objects;

@FunctionalInterface public interface Consumer {

void accept(T t);default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };
}
復制代碼

} 大家看,是不是感覺有些不對呢?Java接口明明不能所有實現方法的,現在卻多了一個default方法被實現,嘿嘿,這是Java8的新特性,這個我會在之后的帖子中繼續和大家分享。大家要注意的是@FunctionalInterface這個注解,它表明這個接口是一個函數式接口,函數式接口的定義就是:一個有且只有一個抽象方法,但是可以有多個非抽象方法的接口。非抽象方法就是default方法,可以有多個,但是抽象方法只能有一個,那么上面關于傳入方法引用怎樣匹配方法簽名和返回值的疑問你們理解了嗎?

就是說在上面的例子中我在show方法定義的Consumer中只有一個抽象方法accept,他是一個無返回值,接受一個泛型參數的方法,而我在調用show方法的時候也傳入了和accept方法返回值一致,參數相同的方法引用,這就是方法重寫,在上面的例子中我傳入System.out::println時就是無形之中創建了一個匿名類,然后重寫了他的accept方法,重寫的方法就是System.out.println()方法。神奇咩?嘿嘿...

等等,還沒完...Consumer接口提供一個無返回值類型接受一個參數的抽象方法供大家使用,那么如果我有其他需求呢?假如我需要一個有返回值的抽象方法供我使用呢?

別急,Java提供了一系列函數式接口來供我們按照需求使用,如果沒有自己需要的接口的話我們也可以自己寫一個函數式接口來使用。

函數式接口 函數描述符 Predicate T->boolean Consumer T->void Function<T,R> T->R Supplier ()->T UnaryOperator T->T BinaryOperator (T,T)->T

BiPredicate<L,R> (L,R)->boolean BiConsumer<T,U> (T,U)->void BiFunction<T,U,R> (T,U)->R 函數描述符是什么呢?這就要說到Lambda表達式了,在下一篇博客中我會講解。(本人是小白大學生一枚,如有不對或者不當之處,還請各位前輩指點,嘿嘿)

轉載于:https://juejin.im/post/5c39af8a518825265c2fd86a

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276207.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276207.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276207.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

猴子排圈求最后編號問題

轉載鏈接&#xff1a;http://www.cnblogs.com/mztest/archive/2013/01/30/2882829.html 一群猴子排成一圈&#xff0c;按1&#xff0c;2&#xff0c;...&#xff0c;n依次編號。然后從第1只開始數&#xff0c;數到第m只,把它踢出圈&#xff0c;從它后面再開始數&#xff0c;再…

若川的2020年度總結,水波不興

前言從2014年開始&#xff0c;每一年都會寫年度總結&#xff0c;堅持了6個年頭。回顧2014&#xff0c;約定2015&#xff08;QQ空間日志&#xff09;2015年總結&#xff0c;淡化舊標簽&#xff0c;無懼未來&#xff08;QQ空間日志&#xff09;2016年度總結&#xff0c;畢業工作2…

sql修改表字段數據類型

--加 ALTER TABLE table2 ADD row_id bigint --刪 ALTER TABLE table2 DROP COLUMN row_id --改 ALTER TABLE 你的表 ALTER COLUMN 列名 你的類型 null declare a varchar(200) select ac.name fr…

關于敏捷開發方法(Agile Software Development)的閱讀筆記

對“敏捷開發”&#xff08;Agile Software Development&#xff09;這個詞&#xff0c;我是在這學期鄒欣老師《現代程序設計》課上第一次聽到的&#xff0c;剛聽到時并不知道其具體指什么&#xff0c;只是從字面上直覺其意思應該是快速開發之類的。這次從 Agile Guide 、 The …

phpbreak跳出幾層循環_PHP跳出循環之“break”

前面給大家講解了PHP控制循環語句&#xff0c;知道了&#xff0c;當我們的程序塊滿足一定的條件后才會跳出循環&#xff0c;而跳出循環則是使用我們的break或者continue關鍵字。本章&#xff0c;將會先給大家講解“break”跳出循環。在前面的講解PHP循環控制語句“while”循環的…

Vuex 4.0 正式發布!新年,官方生態齊聚一堂。

Vuex 4 官方版本正式發布。Vuex 4 的重點是兼容性。Vuex 4 支持 Vue 3&#xff0c;但是仍然提供了與 Vuex 3 完全相同的 API&#xff0c;因此用戶可以在 Vue 3 中直接復用他們現有的 Vuex 代碼。下文會把破壞性的改動列出來&#xff0c;請注意查看。在源碼的 example 文件夾[1]…

原生js實現給指定元素的后面追加內容

參考鏈接&#xff1a;http://www.jb51.net/article/35412.htm 原生js實現給指定元素的后面追加內容 var header1 document.getElementById("header"); var p document.createElement("p"); // 創建一個元素節點 insertAfter(p,header1); // 因為js沒有…

文檔中根元素后面的標記格式必須正確。

文檔中根元素后面的標記格式必須正確。 php或其它語言動態輸出的xml&#xff0c;最開始<標記 前面有空格&#xff0c;最后面>標記 后面有 空格 導致xml解析出錯 解決辦法: var data:String evt.target.data;//兼容FireFox, php輸出的xml data data.substr(data…

lstm數學推導_如何在訓練LSTM的同時訓練詞向量?

你本來也不用自己手動進行詞向量更新啊&#xff0c;你搞這么一出最后收斂到0那不是必然的么&#xff1f; 霍華德 老師的答案已經給你推導出來了。實際上你問的這個問題很簡單——只要把Embedding層本身也當成模型參數的一部分就可以了&#xff0c;一開始不使用外部詞向量&#…

Javascript在頁面加載時的執行順序(轉載)

原文&#xff1a;http://dancewithnet.com/2007/03/22/order-of-execution-of-javascript-on-web/ 一、在HTML中嵌入Javasript的方法 直接在Javascript代碼放在標記對<script>和</script>之間由<script />標記的src屬性制定外部的js文件放在事件處理程序中&a…

TClientDataSet[27]: 字段值的約束(或叫輸入限制)

Required、Precision、MaxValue、MinValue:begin{ Required: 必填字段 }with TIntegerField.Create(Self) do beginFieldName : ID;Required : True;DataSet : ClientDataSet1;end;{ Precision: 浮點數精度}with TFloatField.Create(Self) do beginFieldName : Float;Precision…

年度總結文章的抽獎結果公布

大家好&#xff0c;我是若川。2月4日&#xff0c;發表了我的2020年度總結文章《若川的2020年度總結&#xff0c;水波不興》&#xff0c;本以為閱讀量應該突破一千會比較快&#xff0c;實際上比較艱難&#xff0c;而且還掉粉10來人。2020年運營公眾號以來&#xff0c;不知不覺發…

php 正則表達式 匹配中日韓字符(GBK)

轉載鏈接&#xff1a;http://www.cnblogs.com/ITEagle/archive/2013/01/14/2859775.html 首先是這些非英文字符的編碼范圍&#xff1a; 這里是幾個主要非英文語系字符范圍 2E80&#xff5e;33FFh&#xff1a;中日韓符號區。收容康熙字典部首、中日韓輔助部首、注音符號、日本假…

linux多線程求和_linux 多線程信號處理總結

linux 多線程信號總結(一)1. 在多線程環境下&#xff0c;產生的信號是傳遞給整個進程的&#xff0c;一般而言&#xff0c;所有線程都有機會收到這個信號&#xff0c;進程在收到信號的的線程上下文執行信號處理函數&#xff0c;具體是哪個線程執行的難以獲知。也就是說&#xff…

Elon Musk

人物事件 成長學習 1971年6月28日&#xff0c;埃隆馬斯克在南非的比勒陀利亞出生&#xff0c;他的 埃隆馬斯克 父親是一名南非機電工程師&#xff0c;母親是加拿大人&#xff0c;從事營養師兼模特。[8] 1981年&#xff0c;10歲的馬斯克就擁有了自己的第一臺電腦&#xff0c;并…

真誠推薦這7個大佬的公眾號,碎片化學習

逆水行舟&#xff0c;不進則退。我們的工作已經占用了大塊的時間了&#xff0c;剩下的只有各種碎片&#xff0c;最適合碎片時間學習的&#xff0c;莫過于優質的技術干貨公眾號啦~以下這些是小編精選&#xff0c;里面有很多資訊和資源&#xff0c;內含干貨&#xff0c;希望能給大…

[轉]Windows 7 產品密鑰是否安全

提到Windows 7&#xff08;或Windows Server 2008&#xff09;有些人認為自己的產品密鑰&#xff08;Product Key&#xff09;很安全&#xff0c;甚至在公司內部有些網管也認為公司部署的Windows 7 系統的密鑰不會泄露。但其實并非如此&#xff0c;眾所周知我們的密鑰都是寫在注…

HttpWatch的Result中出現Aborted的原因分析[配圖]

轉載鏈接&#xff1a;http://www.cnblogs.com/yutiansanshou/archive/2013/02/01/2889486.html 我們在使用HttpWatch進行Web調試的過程中有時候會看到非HTTP Status Code&#xff08;狀態碼&#xff09;的值&#xff0c; 例如&#xff1a;(Aborted)。 (Aborted)是HttpWatch中定…

android顯示布局邊界的邊距_Android設計規范 Material Design-Layout(2 度量與邊框)

度量與邊框基準網絡所有組件都與間隔為8dp的基準網格對齊。排版/文字(Type)與間隔為4dp的基準網格對齊。在工具條中的圖標同樣與間隔為4dp的基準網格對齊。這些規則適用于移動設備、平板設備以及桌面應用程序。有關詳細信息請參見組件一節。有關詳細信息請參見字體排版一節。邊…

《大規模分布式系統架構與設計實戰》

《大規模分布式系統架構與設計實戰》 基本信息 作者&#xff1a; 彭淵 叢書名&#xff1a; 大數據技術叢書 出版社&#xff1a;機械工業出版社 ISBN&#xff1a;9787111455035 上架時間&#xff1a;2014-2-21 出版日期&#xff1a;2014 年2月 開本&#xff1a;16開 頁碼&…