Java中雙冒號::的作用舉例詳解
一、定義
雙冒號運算操作符是類方法的句柄,lambda表達式的一種簡寫
表達式:
person -> person.getName();
可以替換成:
Person::getName表達式:
() -> new HashMap<>();
可以替換成:
HashMap::new
二、如何理解
雙冒號(::)運算符在Java 8中被用作方法引用(method reference),方法引用是與lambda表達式相關的一個重要特性。它提供了一種執(zhí)行方法的方法,為此,方法引用需要由兼容的函數(shù)式接口組成的目標類型上下文。使用lambda表達式會創(chuàng)建匿名函數(shù), 但有時候需要使用一個lambda表達式只調用一個已經(jīng)存在的方法(不做其它), 所以這才有了方法引用!
其實,JVM 本身并不支持指向方法引用,過去不支持,現(xiàn)在也不支持。Java 8 對方法引用的支持只是編譯器層面的支持,虛擬機執(zhí)行引擎并不了解方法引用。編譯器遇到方法引用的時候,會像上面那樣自動推斷出開發(fā)者的意圖,將方法引用還原成接口實現(xiàn)對象,或者更形象地說,就是把方法引用設法包裝成一個接口實現(xiàn)對象,這樣虛擬機就可以無差別地執(zhí)行字節(jié)碼文件而不需要管什么是方法引用了。
需要注意的是,方法引用是用來簡化接口實現(xiàn)代碼的,并且凡是能夠用方法引用來簡化的接口,都有這樣的特征:有且只有一個待實現(xiàn)的方法。這種接口在 Java 中有個專門的名稱: 函數(shù)式接口。當試圖用方法引用替代一個非函數(shù)式接口時,會有這樣的錯誤提示: xxx is not a functional interface。
三、使用場景
類型 | 引用語法 | 案例 |
引用靜態(tài)方法 | 類名::靜態(tài)方法名 | Integer::parseInt |
引用特定對象實例方法 | 對象::實例方法名 | System.out::println |
引用特定類型的任意對象的實例方法 | 特定類型::實例方法名 | String::compareToIgnoreCase |
引用超類(父類)實例方法 | super::方法名 | |
引用類構造方法 | 類名::new | ArrayList::new |
引用數(shù)組構造方法 | 數(shù)組類型[]::new | String[]::new |
案例詳解:
引用靜態(tài)方法
import org.junit.Test; import java.util.Arrays; import java.util.List; public class Colon{ @Test public void test(){ List<String> list = Arrays.asList("a", "b","c"); //靜態(tài)方法引用ClassName::methodName list.forEach(Colon:: print); //上一行等價于 //1ist.forEach((x)->Colon.print(x)); } //靜態(tài)方法 public static void print(String s){ system.out.println(s); } }
引用特定對象實例方法
import org.junit.Test; import java.util.Arrays; import java.util.List; public class Colon{ @Test public void test(){ List<string> list = Arrays.asList("a", "b","c");//r實例方法引用instanceRef: :methodName list.forEach(new Colon()::print); //上一行等價于 //iist.forEach((x)->new Colon().print(x)); } //實例方法 public void print(String s){ System.out.println(s); } }
引用特定類型的任意對象的實例方法
import org.junit.Test; import java.util.Arrays; public class Colon{ @Test public void test(){ String[] arr = { "Barbara","James","Mary", "John", "Patricia","Robert","Michae1", "Linda”}; //引用String類型的任意對象的compareToIgnoreCase方法實現(xiàn)忽略大小寫排序 Arrays.sort(arr, String::compareToIgnoreCase); //上一行等價于 //Arrays.sort(arr, (a,b)->a.compareToIgnoreCase(b)); //輸出 for(String s:arr){ System.out.println(s); } }
引用超類(父類)實例方法
import org.junit.Test; import java.util.Arrays; import java.util.List; public class Colon extends BaseColon{ @Test public void test(){ List<string> list = Arrays.asList("a", "b","c"); //實例方法引用instanceRef::methodName list.forEach(super:: print); } } class Basecolon{ //實例方法 public void print(string s){ System.out.println(s); } }
引用類構造方法
一般我們需要聲明接口,該接口作為對象的生成器,通過 類名::new 的方式來實例化對象,然后調用方法返回對象。
//注意:該類無需實現(xiàn)接口 public class Colon{ private String name; private int age; //無參構造 public Colon(){ } //有參構造 public colon(String name, int age){ this.name = name; this.age = age; } public static void main(String[] args){ //無參構造引用 ColonNoParam cnp = Colon::new; colon c1 = cnp.createColon(); System.out.println(c1); //有參構造引用 ColonlithParam cwp = Colon::new; colon c2 = cwp.createColon("小明",20); System.out.println(c2); } //生成toString方法打印查看 @Override public string toString() { return "Colon{" + "name='"+ name + "\"+ ",age=" + age + '}'; } } interface colonNoParam{ //無參方法提供對象 Colon createColon(); } interface ColonwithParam{ //有參方法提供對象(數(shù)據(jù)類型要與colon有參構造函數(shù)對應) colon createColon(String s,int i); }
引用數(shù)組構造方法
我們可以借助jdk自帶的java.util.function.Function類實現(xiàn)對數(shù)組構造函數(shù)的引用。
當然,我們也可以使用@FunctionalInterface自定義函數(shù)式接口來實現(xiàn):
public class Colon{ public static void main(string[] args) { MyArrayFunction<Integer,Colon[]> function = Colon[]::new; //調用apply方法創(chuàng)建數(shù)組,這里的5是教組的長度 colon[] arr = function.apply(5); //循環(huán)輸出-初始都為null for(Colon c:arr){ System.out.println(c); } } } //自定義函教式接口 @FunctionalInterface interface MyArrayFunction<A,T>{ T apply(A a); }
參考博客:http://www.dbjr.com.cn/program/3039116xw.htm
總結
到此這篇關于Java中雙冒號::作用的文章就介紹到這了,更多相關Java 雙冒號::作用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot項目多層級多環(huán)境yml設計詳解
這篇文章主要為大家介紹了SpringBoot項目多層級多環(huán)境yml設計詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03Spring Web MVC框架學習之配置Spring Web MVC
這一篇文章講的是Spring Web MVC各部分的配置方法,包括Java代碼配置和XML文件配置以及MVC命名空間的使用方法。2017-03-03mybatis?plus配置自動create_time和update_time方式
在處理數(shù)據(jù)時,注意時間類型的轉換非常重要,不同編程環(huán)境和數(shù)據(jù)庫對時間數(shù)據(jù)的處理方式各異,因此在數(shù)據(jù)遷移或日常處理中需謹慎處理時間格式,個人經(jīng)驗表明,了解常用的時間轉換函數(shù)和方法能有效避免錯誤,提高工作效率,希望這些經(jīng)驗能為大家?guī)韼椭?/div> 2024-09-09SrpingDruid數(shù)據(jù)源加密數(shù)據(jù)庫密碼的示例代碼
本篇文章主要介紹了SrpingDruid數(shù)據(jù)源加密數(shù)據(jù)庫密碼的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10詳解java中String、StringBuilder、StringBuffer的區(qū)別
這篇文章主要介紹了java中String、StringBuilder、StringBuffer的區(qū)別,文中講解的很清晰,有對于這方面不太懂的同學可以研究下2021-02-02最新評論