JavaSE反射、枚舉、lambda表達(dá)式常用方法舉例
一、反射
- Java的反射(re?ection)機(jī)制是在運(yùn)行狀態(tài)中,對于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;
- 對于任意一個(gè)對象,都能夠調(diào)用它的任意方法和屬性,既然能拿到那么,我們就可以修改部分類型信息;
- 這種動態(tài)獲取信息以及動態(tài)調(diào)用對象方法的功能稱為java語言的反射(re?ection)機(jī)制。
1.1 反射相關(guān)類
類名 | 用途 |
---|---|
Class類 | 代表類的實(shí)體,在運(yùn)行的Java應(yīng)用程序中表示類和接口 |
Field類 | 代表類的成員變量/類的屬性 |
Method類 | 代表類的方法 |
Constructor類 | 代表類的構(gòu)造方法 |
1.2 獲取類中屬性相關(guān)方法
1.2.1 常用獲得類相關(guān)的方法
方法 | 用途 |
---|---|
getClassLoader() | 獲得類的加載器 |
getDeclaredClasses() | 返回一個(gè)數(shù)組,數(shù)組中包含該類中所有類和接口類的對象(包括私有的) |
forName(String className) | 根據(jù)類名返回類的對象 |
newInstance() | 創(chuàng)建類的實(shí)例 |
getName | 獲得類的完整路徑名字 |
1.2.2 示例
獲取類有以下三種方法:
- 通過getClass獲取Class對象
類名 對象名 = new 類名();//初始化一個(gè)對象 Class 類變量名 = 對象名.getClass();
- 直接通過 類名.class 的方式得到。該方法最為安全可靠,程序性能更高
( 這說明任何一個(gè)類都有一個(gè)隱含的靜態(tài)成員變量 class)
Class 類變量名 = 類名.class;
- 通過 Class 對象的 forName() 靜態(tài)方法來獲取,用的最多,
但可能拋出 ClassNotFoundException 異常
try { Class 類變量名 = Class.forName("包名.類名"); } catch (ClassNotFoundException e) { e.printStackTrace(); }
1.2.3 常用獲得類中屬性相關(guān)的方法
方法 | 用途 |
---|---|
getField(String name) | 獲得某個(gè)公有的屬性對象 |
getFields() | 獲得所有公有的屬性對象 |
getDeclaredField(String name) | 獲得某個(gè)屬性對象 |
getDeclaredFields() | 獲得所有屬性對象 |
1.2.4 示例
獲取私有構(gòu)造方法:(展示核心代碼,要捕獲異常)
//第一步:調(diào)用獲取方法,參數(shù)與構(gòu)造方法的類型的.class Constructor<T> constructor = c1.getDeclaredConstructor(String.class , int.class); //第二步:由于是私有的就要設(shè)置為可訪問,相當(dāng)于獲取權(quán)限 constructor.setAccessible(true); //第三步:使用構(gòu)造方法獲取一個(gè)對象 Object o = constructor.newInstance("kun",2.5);
1.2.5 獲得類中注解相關(guān)的方法
方法 | 用途 |
---|---|
getAnnotation(Class annotationClass) | 返回該類中與參數(shù)類型匹配的公有注解對象 |
getAnnotations() | 返回該類所有的公有注解對象 |
getDeclaredAnnotation(Class annotationClass) | 返回該類中與參數(shù)類型匹配的所有注解對象 |
getDeclaredAnnotations() | 返回該類所有的注解對象 |
1.3 反射優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 對于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對于任意一個(gè)對象,都能夠調(diào)用它的任意一個(gè)方法
- 增加程序的靈活性和擴(kuò)展性,降低耦合性,提高自適應(yīng)能力
- 反射已經(jīng)運(yùn)用在了很多流行框架如:Struts、Hibernate、Spring 等等。
缺點(diǎn):
- 使用反射會有效率問題。會導(dǎo)致程序效率降低。
- 反射技術(shù)繞過了源代碼的技術(shù),因而會帶來維護(hù)問題。反射代碼比相應(yīng)的直接代碼更復(fù)雜 。
二、枚舉
枚舉是在JDK1.5以后引入的。
主要用途是:將一組常量組織起來,在這之前表示一組常量通常使用定義常量的方式:public static final
枚舉語法(類內(nèi)方法外):
public enum 枚舉名{ RED,BLACK,GREEN;//定義的都相當(dāng)于常量 }
2.1 常用方法
方法 | 用途 |
---|---|
values() | 以數(shù)組形式返回枚舉類型的所有成員 |
ordinal() | 獲取枚舉成員的索引位置 |
valueOf() | 將普通字符串轉(zhuǎn)換為枚舉實(shí)例 |
compareTo() | 比較兩個(gè)枚舉成員在定義時(shí)的順序 |
枚舉的構(gòu)造方法默認(rèn)是私有的,且只能是私有的。
2.2 優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 枚舉常量更簡單安全 。
- 枚舉具有內(nèi)置方法 ,代碼更優(yōu)雅 。
缺點(diǎn): 不可繼承,無法擴(kuò)展 。
三、枚舉與反射
當(dāng)我們按照前面獲取構(gòu)造方法的方法獲取枚舉的構(gòu)造方法時(shí)匯報(bào)異常:java java.lang.NoSuchMethodException
看源碼會知道是因?yàn)槌宋覀冏约旱臉?gòu)造函數(shù)參數(shù)外,他默認(rèn)后邊還會給參數(shù),也就是說,這里我們參數(shù)給少了。
正確給參數(shù)后還是會報(bào)java.lang.IllegalArgumentException
原因是newInstance方法源碼中有如下判斷:
四、lambda表達(dá)式
Lambda表達(dá)式是Java SE 8中一個(gè)重要的新特性。
lambda表達(dá)式允許你通過表達(dá)式來代替功能接口。
lambda表達(dá)式就和方法一樣,它提供了一個(gè)正常的參數(shù)列表和一個(gè)使用這些參數(shù)的主體(body,可以是一個(gè)表達(dá)式或一個(gè)代碼塊)。
Lambda 表達(dá)式(Lambda expression),基于數(shù)學(xué)中的λ演算得名,也可稱為閉包(Closure)。
4.1 語法
(parameters) -> expression 或 (parameters) ->{ statements; }
- paramaters:類似方法中的形參列表,這里的參數(shù)是函數(shù)式接口里的參數(shù)。這里的參數(shù)類型可以明確的聲明也可不聲明而由JVM隱含的推斷。另外當(dāng)只有一個(gè)推斷類型時(shí)可以省略掉圓括號。
- ->:可理解為“被用于”的意思。
- 方法體:可以是表達(dá)式也可以代碼塊,是函數(shù)式接口里方法的實(shí)現(xiàn)。代碼塊可返回一個(gè)值或者什么都不返回,這里的代碼塊塊等同于方法的方法體。如果是表達(dá)式,也可以返回一個(gè)值或者什么都不返回。
4.2 函數(shù)式接口
一個(gè)接口有且只有一個(gè)抽象方法,其他無關(guān)。
函數(shù)式接口可以加上@FunctionalInterface注解,加上后idea會自動幫你檢驗(yàn)。
4.3 簡化規(guī)則
- 參數(shù)類型可以省略,如果需要省略,每個(gè)參數(shù)的類型都要省略。
- 參數(shù)的小括號里面只有一個(gè)參數(shù),那么小括號可以省略
- 如果方法體當(dāng)中只有一句代碼,那么大括號可以省略
- 如果方法體中只有一條語句,且是return語句,那么大括號可以省略,且去掉return關(guān)鍵字。
4.4 使用示例
MoreParameterNoReturn moreParameterNoReturn = ( a, b)->{ System.out.println("無返回值多個(gè)參數(shù),省略參數(shù)類型:"+a+" "+b); }; OneParameterNoReturn oneParameterNoReturn = a ->{ System.out.println("無參數(shù)一個(gè)返回值,小括號可以勝率:"+ a); }; NoParameterNoReturn noParameterNoReturn = ()->System.out.println("無參數(shù)無返回值,方法體中只有一行代碼");
4.5 變量捕獲
lambda可以自動捕獲上層的變量。
但是捕獲到的變量不能夠在修改,修改就會報(bào)錯(cuò)。
public static void main(String[] args) { int a = 10; NoParameterNoReturn noParameterNoReturn = ()->{ // a = 99; error System.out.println("捕獲變量:"+a); }; noParameterNoReturn.test(); }
4.6 集合中的應(yīng)用
4.7 優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 代碼簡潔,開發(fā)迅速
- 方便函數(shù)式編程
- 非常容易進(jìn)行并行計(jì)算
- Java 引入 Lambda,改善了集合操作
缺點(diǎn):
- 代碼可讀性變差
- 在非并行計(jì)算中,很多計(jì)算未必有傳統(tǒng)的 for 性能要高
- 不容易進(jìn)行調(diào)試
總結(jié)
到此這篇關(guān)于JavaSE反射、枚舉、lambda表達(dá)式常用方法的文章就介紹到這了,更多相關(guān)JavaSE反射、枚舉、lambda表達(dá)式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一文詳解Java中的可變對象(Mutable)與不可變對象(Immutable)
如何在 Java 中創(chuàng)建不可變對象?我以前以為所有對象都是不可變的,因?yàn)槿绻愀淖円粋€(gè) String 實(shí)例的內(nèi)容,它總是會創(chuàng)建一個(gè)新的 String 對象并指向該對象,在本文中,我不僅將分享在 Java 中Immutable的步驟,還將討論可變對象與不可變對象及其優(yōu)缺點(diǎn)2023-11-11Spring Cloud 系列之服務(wù)調(diào)用 OpenFeign的實(shí)現(xiàn)
這篇文章主要介紹了Spring Cloud 系列之服務(wù)調(diào)用 OpenFeign的實(shí)現(xiàn),需要的朋友可以參考下2020-11-11Spring Security動態(tài)權(quán)限的實(shí)現(xiàn)方法詳解
這篇文章主要和小伙伴們簡單介紹下 Spring Security 中的動態(tài)權(quán)限方案,以便于小伙伴們更好的理解 TienChin 項(xiàng)目中的權(quán)限方案,感興趣的可以了解一下2022-06-06SpringBoot JavaMailSender發(fā)送郵件功能
這篇文章主要為大家詳細(xì)介紹了SpringBoot JavaMailSender發(fā)送郵件功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04Elasticsearch8.1中的Script使用實(shí)例深入解讀
這篇文章主要為大家介紹了Elasticsearch8.1中的Script使用實(shí)例深入解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10KotlinScript構(gòu)建SpringBootStarter保姆級教程
這篇文章主要為大家介紹了KotlinScript構(gòu)建SpringBootStarter的保姆級教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09JavaAPI中BigInteger、BigDecimal的使用方法及應(yīng)用
這篇文章主要給大家介紹了關(guān)于JavaAPI中BigInteger、BigDecimal的使用方法及應(yīng)用,BigInteger是Java中用于表示任意大小整數(shù)的類,它提供了加、減、乘、除等多種運(yùn)算方法,適用于大整數(shù)處理和高精度計(jì)算場景,需要的朋友可以參考下2024-11-11Spring AI內(nèi)置DeepSeek的詳細(xì)步驟
Spring AI 最新快照版已經(jīng)內(nèi)置 DeepSeek 了,所以以后項(xiàng)目中對接 DeepSeek 就方便多了,但因?yàn)榭煺瞻鏁泻芏?nbsp;Bug,所以今天咱們就來看穩(wěn)定版的 Spring AI 如何對接 DeepSeek 滿血版,感興趣的小伙伴跟著小編一起來看看吧2025-02-02