程序員內(nèi)功修煉大法【反射、內(nèi)省】(下)
五、內(nèi)省
5.1、JavaBean
JavaBean 是 Java 中最重要的一個可重用的組件(減少代碼重復(fù),可重用,封裝業(yè)務(wù)邏輯,封裝數(shù)據(jù))。
5.1.1、JavaBean 的規(guī)范要求
使用 public 修飾。
字段私有化。
提供 get/set 方法。
公共的無參數(shù)的構(gòu)造器(使用反射,使用字節(jié)碼對象.newInstance去創(chuàng)建對象)。
5.1.2、三大成員
事件
方法
屬性
5.1.3、什么是屬性
JavaBean 可以封裝數(shù)據(jù),就是將數(shù)據(jù)保存到一個 bean 對象的屬性中的。
屬性不是字段,屬性是通過get/set方法推導(dǎo)出來的。
**規(guī)范的get方法/獲取方法/讀方法:**public修飾、無參數(shù)、有返回、get開頭。
**規(guī)范的set方法/設(shè)置方法/寫方法:**public修飾、有參數(shù)、無返回、set開頭。
注意:
只要是標準的get/set方法,就存在屬性,不一定非得是通過工具自動生成的規(guī)范的寫法。
字段是 boolean 的,讀方法不是 get 開頭,而是 is 開頭。
5.2、內(nèi)省的概述
JavaBean是一個非常常用的組件,無外乎就是操作里面的屬性。而之前我們要獲取JavaBean中的方法,如果使用反射非常麻煩,于是SUN公司專門提供了一套操作 JavaBean 屬性的API: 內(nèi)省(Introspector)。
5.3、內(nèi)省的作用
獲取到屬性名和屬性類型等相關(guān)狀態(tài)信息。
獲取屬性對應(yīng)的讀寫方法操作屬性的值等操作方式。
5.4、內(nèi)省常用的API
通過字節(jié)碼對象,獲取到JavaBean的描述對象,返回 JavaBean的描述對象
public static BeanInfo getBeanInfo(Class beanClass, Class stopClass);
通過 JavaBean 描述對象獲取屬性描述器
PropertyDescriptor[] getPropertyDescriptors();
通過屬性描述器,獲取到屬性名、屬性類型、讀寫(getter/setter)方法
獲取屬性名:public String getName();
獲取屬性類型:public Class> getPropertyType();
獲取讀方法(getter):public Method getReadMethod();
獲取寫方法(setter):public Method getWriteMethod();
通過字節(jié)碼對象來獲取BeanInfo對象的時候,默認會內(nèi)省當前字節(jié)碼對象以及其所有的父類的信息。比如:getBeanInfo(A.class),其實它也會內(nèi)省A的父類,如Object的信息。一般來說,我們不關(guān)心父類的屬性相關(guān)信息,此時可以調(diào)用getBeanInfo的重載方法:getBeanInfo(beanClass,stopClass)。
示范:BeanInfo beanInfo = Introspector.getBeanInfo(Person.class,Object.class);
package com.day03.IntrospectorDemo; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; /** * @author Xiao_Lin * @date 2020/12/29 13:37 */ public class TestIntrospector { public static void main(String[] args) throws Exception { //創(chuàng)建對象 Student student = Student.class.newInstance(); //把 JavaBean 轉(zhuǎn)成 beanInfo BeanInfo beanInfo = Introspector.getBeanInfo(student.getClass(),Object.class); //通過通過beanInfo獲取所有屬性 PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); //遍歷屬性描述器數(shù)組,獲取到每個屬性描述器 for (PropertyDescriptor pd : propertyDescriptors) { //獲取屬性名 System.out.println("屬性名 = " + pd.getName()); //獲取屬性類型 System.out.println("屬性類型 = " + pd.getPropertyType()); //獲取屬性的getter/setter方法 Method getMethod = pd.getReadMethod(); System.out.println("get方法 = " +getMethod); Method setMethod = pd.getWriteMethod(); System.out.println("set方法 = " +setMethod); //調(diào)用age屬性的set方法 if ("age".equals(pd.getName())){ //執(zhí)行age的set方法,invoke參數(shù)含義是給哪個對象賦予哪個值 setMethod.invoke(student,22); } //再次執(zhí)行g(shù)et方法 System.out.println(student.getAge()); } } }
5.5、JavaBean 和 Map 之間的轉(zhuǎn)化
map和JavaBean的結(jié)構(gòu)很類似,我們可以將 map 和 JavaBean 相互轉(zhuǎn)換.將key和屬性名一 一對應(yīng)起來
5.5.1、JavaBean轉(zhuǎn)map
// Javabean 轉(zhuǎn) map public static Map
public class BeanMap { public static void main(String[] args) throws Exception{ Map
5.5.2、map轉(zhuǎn)JavaBean
//map轉(zhuǎn)JaveBean,這里使用泛型 public static
六、注解
6.1、注解介紹
我們可以使用注解來修飾類中的成員信息,注解其實就是Annotation。
6.2、定義格式
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface 注解名 { }
定義格式:@interface 注解名
使用格式:@注解名(屬性名=屬性值, 屬性名=屬性值)
注解貼在程序元素上,想要擁有某一些功能,必須有三個角色去參與:
注解本身
被貼的程序元素
第三方程序,使用反射給注解賦予功能(在注解的背后,一定有一段代碼給注解賦予功能)。
6.3、內(nèi)置注解
@Override 限定覆寫父類方法
@Deprecated 標記已過時,不推薦使用.在JDK5之前,使用文檔注釋來標記過時
@SuppressWarings 抑制編譯器發(fā)出的警告
@Functionallnterface 標記該接口是一個函數(shù)接口(JDK1.8開始出現(xiàn)的)
6.4、元注解
注解:用來貼在類/方法/變量等之上的一個標記,第三方程序可以通過這個標記賦予一定功能。
元注解:在定義注解的時候用來貼在注解上的注解,用來限定注解的用法。他囊括了三個注解
6.4.1、@Target
表示注解可以貼在哪些位置(類,方法上,構(gòu)造器上等等).位置的常量封裝在ElementType枚舉類
中。
ElementType.ANNOTATION_TYPE只能修飾類。
ElementType.CONSTRUCTOR只能修飾構(gòu)造方法。
ElementType.FIELD只能修飾字段(屬性),包括枚舉常量。
ElementType.LOCAL_VARIABLE只能修飾局部變量。
ElementType.METHOD只能修飾方法。
ElementType.PACKAGE只能修飾包。
ElementType.PARAMETER只能修飾參數(shù)。
ElementType.TYPE只能修飾類,接口,枚舉。
6.4.2、@Retention
表示注解可以保存在哪一個時期,表示時期的值,封裝在RetentionPolicy枚舉類中。
6.4.3、@Documented
使用@Documented標注的標簽會保存到API文檔中。
6.4.4、@Inherited
@Inherited標注的標簽可以被子類所繼承。
標記已過時,不推薦使用.在JDK5之前,使用文檔注釋來標記過時
@SuppressWarings 抑制編譯器發(fā)出的警告
@Functionallnterface 標記該接口是一個函數(shù)接口(JDK1.8開始出現(xiàn)的)
6.4、元注解
注解:用來貼在類/方法/變量等之上的一個標記,第三方程序可以通過這個標記賦予一定功能。
元注解:在定義注解的時候用來貼在注解上的注解,用來限定注解的用法。他囊括了三個注解
6.4.1、@Target
表示注解可以貼在哪些位置(類,方法上,構(gòu)造器上等等).位置的常量封裝在ElementType枚舉類
中。
ElementType.ANNOTATION_TYPE只能修飾類。
ElementType.CONSTRUCTOR只能修飾構(gòu)造方法。
ElementType.FIELD只能修飾字段(屬性),包括枚舉常量。
ElementType.LOCAL_VARIABLE只能修飾局部變量。
ElementType.METHOD只能修飾方法。
ElementType.PACKAGE只能修飾包。
ElementType.PARAMETER只能修飾參數(shù)。
ElementType.TYPE只能修飾類,接口,枚舉。
6.4.2、@Retention
表示注解可以保存在哪一個時期,表示時期的值,封裝在RetentionPolicy枚舉類中。
6.4.3、@Documented
使用@Documented標注的標簽會保存到API文檔中。
6.4.4、@Inherited
@Inherited標注的標簽可以被子類所繼承。
API 開發(fā)者
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。