




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、源文件來自y2筆記反射(reflect)反射即將class類中的所有的成員映射為相應的對象。要學習反射那么需要先了解和掌握以下幾個類:類描述class描述所有的class文件的共性filed描述的是class文件的中的屬性的共性constructor描述的是class文件中的構造函數的共 性method描述的是class文件中的函數的共性1.獲取指定類的class對象方式一:類名.class方式二:對象名.getclass()方式三:forname(string classname)該方法是 class類的靜態(tài)方法推薦舉例1: 獲取字符串類的 class對象。public static voi
2、d main(string口 args)throws exception /使用不同的方式會過去 class對象class clazz1 = string.class ;class clazz2 = new string( "zhangsan" ).getclass();/參數必須指定類的全名(類的全限定名)class clazz3 = class.forname ( "java.lang.string");/ class文件時候獨一無二的,那么 class對象也應該是單例的system. out .println(clazz1 = clazz2);/
3、truesystem. out .println(clazz2 = clazz3);/ true以上的方式都可以獲取指定類的class對象,在實際的開發(fā)中到底要使用哪一一般的情況下我們都需要在不知道類名的情況下獲取類的class對象并進而獲取類中包含的成員進行操作。大家可以參考tomcat的一個基本的 server.xml文件<resource name="userdatabase" auth="container"type="org.apache.catalina.userdatabase”description="user
4、database that can be updated and saved" factory="org.apache.catalina.users.memoryuserdatabasefactory"pathname="conf/tomcat-users.xml” />2.將class對象中的屬性進行反射為filed對象 常用的獲取屬性字段的方法方法field口 getdeclaredfields()描述獲取所有聲明的字段數組對象field getfields()fieldgetdeclaredfield(string獲取所有的聲明的共有字段數組
5、對象 獲取指定名稱的聲明的字段對象name)field getfield(string name)獲取指定名稱的聲明的共有字段對象舉例1:獲取所有的聲明字段數組對象public static void main(string口 args)throws exception / 獲取shape類的class對象 class clazz = class.forname ("cn.sve.bean.shape" );/獲取所有的屬性field 口 fs = clazz.getdeclaredfields(); system. out .println(fs. length );/
6、2/獲取所有共有的屬性 fs = clazz.getfields();system. out .println(fs. length );/ 1/獲取指定名字的私有的屬性 field field = clazz.getdeclaredfield("x");system. out .println(field);/獲取指定名字的共有的屬性 field = clazz.getfield("y");system. out .println(field);舉例2:調用field類的方法進行字段對象的操作。throws exception public stati
7、c void main(string口 args)/ 獲取shape類的class對象class clazz = class.forname ( "cn.sve.bean.shape" );/獲取所有的屬性field 口 fs = clazz.getdeclaredfields();system. out .println(fs. length );/ 2/獲取所有共有的屬性fs = clazz.getfields();system. out .println(fs. length );/ 1shape shape = new shape(); / 20/獲取指定名字的私有
8、的屬性field field = clazz.getdeclaredfield("x");system. out .println(field);system. out .println( /獲取x的屬性值,彳 field.setaccessible( system. out .println( / 設置x的屬性值 field.set(shape, 20); system. out .println("屬性名:"+field.getname();/操作私有的屬性x需要暴力的反射true );”設置之前的 x值:"+field.get(shape
9、);”設置之后的 x值:"+field.get(shape);/獲取指定名字的共有的屬性field = clazz.getfield("y");system. out .println(field);/給屬性y進行設置值system. out .println( "屬性名:"+field.getname();/獲取設置屬性值之前的值system. out .println("設置之前的 y值:"+field.get(shape);/20 field.set(shape,30);/ 30system. out .println
10、("設置之后的 y值:"+shape. y);/ 30 以上的代碼可以通過程序進行反射類中的屬性字段并操作,但是沒有進行靜態(tài)屬 性的反射和操作。舉例3:反射靜態(tài)的成員屬性。throws exception public static void main(string口 args)/ 獲取shape類的class class clazz = class./獲取共有的靜態(tài)屬性field field = clazz.getfield(對象forname("cn.sve.bean.shape");system. field.set( system.outout.
11、println( null , 40); .println("z");”設置之前的z值:"+field.get("設置之后的z值:"+field.get(null );null );3 .將class對象中的方法進行反射為method對象。public static void main(string口 args)throws exception / 獲取shape類的class對象class clazz = class.forname ( "cn.sve.bean.shape" );/獲取所有的聲明的方法method ths
12、 = clazz.getdeclaredmethods();system. out .println(ths. length ); / 2/獲取私有的帶參數的sayhello 方法method sayhello = clazz.getdeclaredmethod("sayhello string. class 匚system. out .println(sayhello);/調用私有的方法sayhello.setaccessible(true );sayhello.invoke( new shape(), "zhangsan" );/獲取所有的共有的方法ths =
13、 clazz.getmethods();system. out .println(ths. length ); / 10/獲取帶參數的共有的方法method greet = clazz.getdeclaredmethod("greet" ,string. class );system. out .println(greet);/方法的調用greet.invoke( new shape(), "zhangsan" );4 .將class對象中的構造函數進行反射為constructor對象。public static void main(string口 ar
14、gs)throws exception / 獲取shape類的class對象class clazz = class.forname ("cn.sve.bean.shape" );/獲取所有的聲明的構造函數constructor cons = clazz.getdeclaredconstructors();system. out .println(cons. length );/ 3/獲取帶參數的私有的構造函數對象 constructor con =clazz.getdeclaredconstructor(int . class , int . class); system.
15、 out .println(con); /暴力反射私有的構造函數創(chuàng)建對象 con.setaccessible( true ); shape myshape = (shape) con.newinstance(400,500); system. out .println(myshape.getx()+"," +myshape. y);/獲取所有的共有的構造函數 cons = clazz.getconstructors(); system . out .println(cons. length );/ 2con = clazz.getconstructor(int . clas
16、s );system. out .println(con); /調用構造函數創(chuàng)建對象 shape shape = (shape) con.newinstance(100); system. out .println(shape.getx(); 面試題:請簡單的敘述出你所可以創(chuàng)建的對象的幾種方式? 第一種:直接使用new關鍵字 第二種:construnctor.newinstance 第三種:枚舉 第四種:單例、工廠模式內省(introspect)其實在以上的反射技術體驗中我們發(fā)現其實反射的對象一般是一個具有特定功 能的一個類。引入一個基本的概念:javabean如果一個類提供了封裝好的屬性、構
17、造函數(無參數)、共有的get和set方法以及簡單的業(yè)務邏輯方法那么將這樣的一個類稱之為javabeangfeo對于一個javabean的操作無非就是給屬性值進行操作或函數的調用。使用反射比較繁瑣,那么 sun就提供了內省的技術方便大家進行 javabea卷的 操作。類描述beaninfo對javabean!行描述的接口introspector描述所有的javabean的成員類propertydescriptor描述的是javabean的屬性類舉例1:使用屬性描述器類操作javabeanh性。創(chuàng)建一個book的javabean類public class book privatestringna
18、me;/ nullprivatestringauthor ;/ nullprivatedoubleprice ;/ / 0.0privatedatedate ;/ nullpublicbook() super ();public book(string name, string author, double price, date date) super ();this . name = name;this . author = author;this . price = price;this . date = date;/ 省略get和set方法 使用內省技術進行簡單的屬性的操作。publi
19、c static void main(string口 args)throws exception/獲取一個屬性的描述器對象就相當于獲取了屬性的名、set和get方法propertydescriptor pd =newpropertydescriptor( "name" ,book. class ) ; / 獲取set方法 method set = pd.getwritemethod(); /調用該方法設置屬性的值 book book = new book(); system. out .println( "設置前獲取 name 屬性值:"+book.ge
20、tname();set.invoke(book, "javase 進階”);system. out .println( "設置后獲取 name 屬性值:"+book.getname();/ 獲取get方法method get = pd.getreadmethod();system. out .println(get.invoke(book,null );以上的代碼每次都只能操作一個屬性,這樣就比較繁瑣??梢允褂闷渌念愔苯?獲取所有的屬性描述器通過循環(huán)來直接操作。public static void main(string口 args)throws excepti
21、on/ 獲取指定的beaninfo 對象beaninfo info = introspector.getbeaninfo (book. class );/獲取book類中的所有的屬性的描述器對象propertydescriptor口 pds = info.getpropertydescriptors();/輸出長度system. out .println(pds. length );/查看數組的第一個屬性描述器是誰propertydescriptor pd = pds0;/作者system. out .println(pd.getname();book book = new book();/給
22、書設置作者信息pd.getwritemethod().invoke(book,"zhangsan" );system. out .println(pd.getreadmethod().invoke(book, null » 總結:其實發(fā)現在使用內省進行屬性操作的時候要結合反射一起使用。 面試題:一個javabean中為什么必須要提供一個無參數的構造函數? 原因一:為了可以做父類。原因二:為了可以使用反射創(chuàng)建對象。beanutils 工具在實際的開發(fā)中我們經常需要將用戶的錄入的數據進行封裝為對象,那么如果使用反射和內省技術就會變得吃力。因此本節(jié)主要給大家講解一個開源
23、的操作 javabea巾勺一個工具即beanutils。下載:beanutils-1.8.0.zipcommons-logging.jar包的引入:在項目中創(chuàng)建一個文件夾如libs,然后將整個項目需要的第三方的jar包可以直接 拷貝帶該目錄,隨后打開該目錄全選 右鍵 build path add path 看到奶瓶 子即可舉例1:使用beanutils工具封裝用戶提交的數據。public staticvoid main(string口 args)throws exception /模擬用戶的輸入的數據如下string name ="xml基礎”
24、;string author ="zhangsan" ;string price ="99.99"string date = "2016-07-07"book book =new book();/任務是將以上的屬性設置給指定的book對象beanutils.setproperty (book,"name" , name);beanutils.setproperty (book,"author" , author);beanutils.setproperty (book,"price&q
25、uot; ,price );/查看屬性是否封裝好 system. out .println(book); 發(fā)現使用上面的代碼可以省略基本數據類型的轉型的問題。進而提高代碼的開發(fā)效率。舉例2:自定義一個類型轉換器類。public static void main(string口 args)throws exception /模擬用戶的輸入的數據如下string name ="xml基礎”;string author ="zhangsan" ;string price ="99.99"string date ="2016-07-07&qu
26、ot;book book =new book();/*注冊一個自己的轉換器converter指定具體的轉換器clazz遇到什么類型調用上面的轉換器*/convertutils. register ( new converter() /回調方法 ©override public object convert(class type, object value) if(value =null )returnnull ;/ 轉換為stringstring data = (string)value;/將指定格式的字符串轉換為datesimpledateformat format =newsim
27、pledateformat( "yyyy-mm-dd" );date date = null ;try date = format.parse(data);return date; catch (parseexception e) e.printstacktrace(); return null ;,date. class );/任務是將以上的屬性設置給指定的book對象beanutils.setproperty(book,"name" , name);beanutils.setproperty(book,"author" , aut
28、hor)beanutils.setproperty(book,"price" ,price );beanutils.setproperty(book,"date" ,date );/查看屬性是否封裝好system. out .println(book);如果每次遇到一個復雜類型都需要自定義轉換器,那樣的話實在麻煩。大家看在 開發(fā)的時候可以先查看該接口是否提供了有效的實現類。convertutils.register(new datelocaleconverter(), date.class);其實真正的封裝好的數據需要存儲在數據庫中,那么 javabea
29、n的數據類型應該 和數據庫的數據類型保持一致,那么在聲明持久化 javabean的時候需要全部為 數據庫的基本數據類型。因此大家在javabean中需要導入的是java.sql.date類,這樣就直接可以將日期自 動轉換了。舉例3:實現封裝好的javabeam象的屬性拷貝。/實現屬性封裝數據的一個拷貝book copy = new book();system. out .println(copy);propertyutils. copyproperties (copy, book);system. out .println(copy);思考:如果使用beanutils封裝用戶的數據,那么也就是
30、一個一個設置?。控M不 是也很麻煩?其實在真是的環(huán)境中我們可以直接獲取用戶提交的所有的數據信息,只需要進行遍歷即可,但是為了方便快速的設置,那么可以將 javabean中的屬性名和用戶 提交的數據名保持一致??蚣荏w驗其實所謂的框架就是通過一些配置文件來將需要運行的模塊以及類、方法在軟件啟動的時候自動運行。如果將需要運行類以及模塊配置在文件中那么便于后期的 一個維護。1 .創(chuàng)建一個配置文件如下run=cn.sve.service.userserviceme=autorunvalue=jack,lucy2 .創(chuàng)建兩個實現接口的服務類userservice.javapublic class users
31、ervice implements service/提供自動運行的方法public void autorun(string names)/使用,號切割用戶列表string 口 ns = names.split(",");/遍歷for (string name:ns)system. out .println( "姓名:"+name);startservice.javapublic class startservice implements service /提供自動運行的方法public void autorun(string names)/使用,號切割用
32、戶列表string 口 ns = names.split(",");/遍歷for (string name:ns)system. out .println(name);以上的兩個類擁有共同的方法因此可以抽取為接口service.javapublic interface service /提供自動運行的方法 public abstract void autorun(string names);throws exception3 . 直接編寫一個main.java進行邏輯處理 public class main public static voidmain(string口 ar
33、gs)/ 1.獲取配置信息properties ps =new properties。;/ 2.裝載文件數據ps.load( new fileinputstream(/ 3.獲取數據string str_clazz = ps.getproperty(string str_method = ps.getproperty(string str_value = ps.getproperty(/ 4.反射獲取class對象new file( "sve.ini""run");"me");"value"););class cl
34、azz = class.forname (str_clazz);/ 5.創(chuàng)建對象null );null );constructor con = clazz.getconstructor(service service = (service)con.newinstance(/ 6.調用相關的方法method method = clazz.getmethod(strmethod, string. method.invoke(service, str value);這樣的話就基本的實現了一個框架的模擬, 大家以后就可以同配置文件的形式修 改程序運行的服務類了。javase的路徑問題舉例1:讀取項目根目錄下的數據。privatestatic void readroot()throws filenotfoundexception,ioexceptionbufferedreader br =newbufferedreader(new filereader(new file( "sve.txt");string l
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 湘藝版四年級上冊音樂教案- 第五課(演唱) 踩雨
- 2025年印刷品、記錄媒介復制品項目合作計劃書
- 大數據技術助力提升教學質量研究
- 教育技術在不同領域的應用及前景分析
- 從教育心理學看學校教育與家庭教育的結合
- 教師專業(yè)成長與教育法的緊密結合
- 心理資本開發(fā)教育心理學在人力資源培訓中的實踐
- 2025屆安徽省合肥市巢湖市匯文實驗學校物理高二下期末質量跟蹤監(jiān)視試題含解析
- 在線教育與遠程教學下的教師能力提升
- 合同變更的處理流程題目
- 三級教育培訓試題及答案
- 河南省鄭州市2024-2025學年高一下期期末考試數學試卷
- 急救護理培訓結業(yè)測試題庫
- 2025年河北公安廳交通管理總隊高速交警招聘考試筆試試題(含答案)
- 懷舊廟會活動方案
- 幼兒新年音樂活動方案
- 衛(wèi)生院艾滋病培訓課件
- 精密空調原理培訓
- GB/T 33804-2025肥料級腐植酸鉀
- 2025安全生產月主題宣講課件十:主要負責人安全公開課
- 加氣站氣瓶充裝質量保證體系手冊2024版
評論
0/150
提交評論