Java編程學(xué)習(xí):SAO操作-使用lambda代替字符串!

Java是一種可以撰寫(xiě)跨平臺(tái)應(yīng)用軟件的面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言。Java 技術(shù)具有卓越的通用性、高效性、平臺(tái)移植性和安全性,廣泛應(yīng)用于PC、數(shù)據(jù)中心、游戲控制臺(tái)、科學(xué)超級(jí)計(jì)算機(jī)、移動(dòng)電話和互聯(lián)網(wǎng),同時(shí)擁有全球最大的開(kāi)發(fā)者專業(yè)社群。

給你學(xué)習(xí)路線:html-css-js-jq-javase-數(shù)據(jù)庫(kù)-jsp-servlet-Struts2-hibernate-mybatis-spring4-springmvc-ssh-ssm

Java8新增了lambda表達(dá)式,最常見(jiàn)的用法是配合 Stream 做集合操作。下面是一種類似彩蛋的東西可以妙用到某些場(chǎng)合。

一般用法,比如下面這樣

Optional.of(1L).ifPresent(number -> { System.out.println(number);});

或者簡(jiǎn)化成這樣

Optional.of(1L).ifPresent(System.out::println);

有什么辦法能獲取到 System.out::println 里面的方法名字符串 String methodName = "println" ?

啥效果?

小編推薦一個(gè)學(xué)Java的學(xué)習(xí)裙【 七六零,二五零,五四一 】,無(wú)論你是大牛還是小白,是想轉(zhuǎn)行還是想入行都可以來(lái)了解一起進(jìn)步一起學(xué)習(xí)!裙內(nèi)有開(kāi)發(fā)工具,很多干貨和技術(shù)資料分享!

執(zhí)行代碼

FnConverter fnConverter = new FnConverter<>();String fieldName = fnConverter.convertFnToString(Foo::getBar);System.out.println("方法名:"+fieldName);

輸出

方法名:bar

怎么做?

第一步:定義一個(gè) FunctionalInterface (敲黑板,畫(huà)重點(diǎn) extends Serializable )

/** * @author Frank */@FunctionalInterfacepublic interface Fn extends Serializable { Object apply(T source);}

第二布:準(zhǔn)備個(gè)類(醬油)

import lombok.Data;/** * @author liuyuyu */@Datapublic class Foo { private Integer bar;}

第三步:獲取 Fn 的信息的工具類

import java.beans.Introspector;import java.lang.invoke.SerializedLambda;import java.lang.reflect.Method;/** * @author Frank */public class Reflections { private Reflections() { } public static String fnToFieldName(Fn fn) { try { Method method = fn.getClass().getDeclaredMethod("writeReplace"); method.setAccessible(Boolean.TRUE); SerializedLambda serializedLambda = (SerializedLambda) method.invoke(fn); String getter = serializedLambda.getImplMethodName(); String fieldName = Introspector.decapitalize(getter.replace("get", "")); return fieldName; } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } }}

畫(huà)重點(diǎn) SerializedLambda serializedLambda = (SerializedLambda) method.invoke(fn);

第四步:寫(xiě)個(gè)梨子跑起來(lái)

/** * @author liuyuyu */public class FnConverter { public String convertFnToString(Fn fn){ return Reflections.fnToFieldName(fn); } public static void main(String[] args) { FnConverter fnConverter = new FnConverter<>(); String fieldName = fnConverter.convertFnToString(Foo::getBar); System.out.println("方法名:"+fieldName); }}

Run

方法名:bar

啥原理?

Serializable 是Java對(duì)象序列化的接口,凡是實(shí)現(xiàn)這個(gè)接口(interface是繼承,也算)Java都要提供序列化和反序列化的方法( ObjectInputStream/ObjectOutputStream 可能會(huì)讓你想起點(diǎn)什么)。

但是lambda比較特殊,它是一個(gè)方法,可以認(rèn)為是一個(gè)動(dòng)作(或者說(shuō)是功夫?比如九陰真經(jīng)),沒(méi)辦法直接保存,Java提供了 SerializedLambda 這個(gè)類保存lambda的信息。

public final class SerializedLambda implements Serializable { private static final long serialVersionUID = 8025925345765570181L; private final Class capturingClass; private final String functionalInterfaceClass; private final String functionalInterfaceMethodName; private final String functionalInterfaceMethodSignature; private final String implClass; private final String implMethodName; private final String implMethodSignature; private final int implMethodKind; private final String instantiatedMethodType; private final Object[] capturedArgs; //省略之后代碼}

小編推薦一個(gè)學(xué)Java的學(xué)習(xí)裙【 七六零,二五零,五四一 】,無(wú)論你是大牛還是小白,是想轉(zhuǎn)行還是想入行都可以來(lái)了解一起進(jìn)步一起學(xué)習(xí)!裙內(nèi)有開(kāi)發(fā)工具,很多干貨和技術(shù)資料分享!

知道了這個(gè)隱藏(彩)特性(蛋),我們回頭看看剛才黑板上畫(huà)的重點(diǎn)

@FunctionalInterface //lambdapublic interface Fn extends Serializable //序列化接口

兩個(gè)條件滿足

因?yàn)檫@個(gè)東西是個(gè)隱藏(彩)特性(蛋),我們不能直接獲取到 SerializedLambda 。直接上反射!

SerializedLambda serializedLambda = (SerializedLambda) method.invoke(fn);

這樣,我們就可以獲取到lambda的方法名

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)自https://blog.csdn.net/sinat_38259539/article/details/71...
    扎Zn了老Fe閱讀 588評(píng)論 0 4
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,612評(píng)論 18 399
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,500評(píng)論 19 139
  • 4月21日,李文博士代表混序部落與前萬(wàn)科副總裁、優(yōu)客工場(chǎng)創(chuàng)始人毛大慶先生(慶慶哥),在首部社群眾籌電影《滅口》拍攝...
    曹霞飛閱讀 822評(píng)論 0 0
  • 據(jù)央視駐平壤記者趙淼5月22日?qǐng)?bào)道,受邀見(jiàn)證朝鮮關(guān)閉核試驗(yàn)場(chǎng)的外媒記者團(tuán)今天下午已抵達(dá)朝鮮元山機(jī)場(chǎng)正在辦理入關(guān)手續(xù)。
    林貝貝fy閱讀 200評(píng)論 0 0

友情鏈接更多精彩內(nèi)容