java反射機制: 思想:將一個類的各個組件映射成對應(yīng)的對象,從而可以從對整體的操作轉(zhuǎn)移到對部分組件的操作.
屬性:Field 方法:Method 包:Package 構(gòu)造方法:Constructor
核心類Class:
Java程序在運行時,Java運行時系統(tǒng)一直對所有的對象進行所謂的運行時類型標識,這項信息紀錄了每個對象所屬的類。虛擬機通過使用運行時類型信息選擇正確方法去執(zhí)行,用來保存這些類型信息的類是Class類。
Class類封裝一個對象和接口運行時的狀態(tài),當裝載類時,Class類型的對象自動創(chuàng)建。 每個對象都是相應(yīng)的一個Class的實例,一組對象的所有成員變量具有相同的屬性和方法,那么每個組員元素在jvm運行時已相同的Class對象出現(xiàn).每個組對象的基類為Class,Class對象記錄相應(yīng)的對象的所有基本信息,以字節(jié)碼的形式存儲在內(nèi)存靜態(tài)區(qū)域
通俗來講:Class類比一個模具(類),模具定義了一個產(chǎn)品的規(guī)格,例如材料、尺寸、加工工藝,按照模具的使用要求就可以實現(xiàn)產(chǎn)品(對象實例)的批量生產(chǎn)
測試類:
package com.zhiwei.reflection;class Person{ PRivate String name; private int age; private String dept="Science"; public Person(String name, int age) { super(); this.name = name; this.age = age; } public void show(){ System.out.println(name+"--"+age+"--"+dept); }}Class獲取的三種方式:
Person person = new Person("squirrel", 10); Class clazz01 = Person.class; Class clazz02 = Class.forName("com.zhiwei.reflection.Person"); Class clazz03 = person.getClass(); System.out.println(clazz01 == clazz02); System.out.println(clazz01 == clazz03);結(jié)果:true true 結(jié)論:三種方式獲取的得到的對象是一樣的
①:對類的屬性操作
//獲取定義的屬性,如果使用getFields()方法,private類型的屬性不會顯示 Field[] fields = clazz01.getDeclaredFields(); for(Field field:fields){ System.out.println("屬性名:"+field.getName()+",屬性類型:"+field.getType()); }結(jié)果: 
②:對類的普通方法操作:
Method[] methods = clazz01.getMethods(); //獲取所有方法 for(Method method:methods){ System.out.println("方法名:"+method.getName()+",參數(shù):"+method.getParameterCount()+",參數(shù)類型:"+method.getParameterTypes()); }結(jié)果: 
③:對類的構(gòu)造函數(shù)的操作
Constructor[] constructors = clazz01.getConstructors(); for(Constructor constructor:constructors){ Parameter[] parameters = constructor.getParameters(); StringBuffer sb = new StringBuffer("構(gòu)造函數(shù)參數(shù)類型:"); for(Parameter parameter:parameters){ sb.append(parameter.getParameterizedType()+","); } System.out.println(sb.deleteCharAt(sb.length()-1)); }結(jié)果: 
④:構(gòu)造函數(shù)的應(yīng)用
Constructor constructor = constructors[0]; Person ps = (Person) constructor.newInstance("zhangsan",14); //對象實例化 ps.show();結(jié)果: 
Java反射機制的一個小案例01:修改對象實例的屬性值
person.show(); Field field = clazz01.getDeclaredField("dept"); field.setaccessible(true); System.out.println("原屬性值:"+(String)field.get(person)); field.set(person, "music"); person.show();結(jié)果:
分析:從person的show()方法打印的信息看出,person實例的屬性信息確實被修改。
相當于獲取一個產(chǎn)品的設(shè)計參數(shù)
field.set(person, "music");person這個產(chǎn)品的設(shè)計參數(shù)dept需要個性化定制,改為“music”,set就是將設(shè)計參數(shù)和產(chǎn)品進行關(guān)聯(lián),表面只改person的dept屬性值
補充:
field.setAccessible(true);這個用于設(shè)置對象的private修飾的屬性訪問特定,否則private修飾的屬性無法直接訪問
Java反射機制的一個小案例02:通過反射機制調(diào)用目標方法(回調(diào)機制在框架中經(jīng)常使用)
Method method = clazz01.getMethod("show"); method.invoke(person);invoke方法第一個參數(shù)為目標對象,第二個參數(shù)開始都是方法的參數(shù),這里利用JDK的可變參數(shù)的特性
新聞熱點
疑難解答