您好,登錄后才能下訂單哦!
今天小編給大家分享一下Java反射機(jī)制怎么使用的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語言的反射機(jī)制。要想解剖一個(gè)類,必須先要獲取到該類的字節(jié)碼文件對(duì)象。而解剖使用的就是Class類中的方法.所以先要獲取到每一個(gè)字節(jié)碼文件對(duì)應(yīng)的Class類型的對(duì)象.
第一種方式:
通過調(diào)用java.lang.Class
類下的靜態(tài)方法:static Class forName(String className)
注意:
參數(shù)是一個(gè)帶有包名的完整類名(同目錄下的可以只寫類名)。
拋出編譯時(shí)異常:ClassNotFountException
。
該方法會(huì)導(dǎo)致相應(yīng)的類被類加載。
代碼如下:
public class MyClass { static{ System.out.println("靜態(tài)代碼塊執(zhí)行!"); } } class Test{ Class c = Class.forName("MyClass"); }
編譯結(jié)果:
第二種方式:
Object類下有個(gè)方法: public final Class getClass()
----- 返回此對(duì)象的Class。
代碼如下:
Date d = new Date(); Class c2 = d.getClass();
第三種方式:
Java種任何一種類型,包括基本數(shù)據(jù)類型,都有class靜態(tài)屬性,直接通過 類名.class
,就可以返回相應(yīng)的Class類。
代碼如下:
Class c = Date.class;
相關(guān)方法:
public Field[] getFields() ------- java.lang.Class中的方法,將類中public修飾的屬性以數(shù)組的形式返回
public Field[] getDeclaredFields() ------ java.lang.Class中的方法,將類中所有的屬性以數(shù)組的形式返回
public Class getType() ------ java.lang.reflect.Field中的方法,獲取屬性的類型并返回
public int getModifiers() ----- java.lang.reflect.Field中的方法,獲取屬性的修飾符,并以整數(shù)編碼的形式返回(一個(gè)整數(shù)編碼可能代表多個(gè)修飾符)
static String toString(int mod) ------ java.lang.reflect.Modifier中的靜態(tài)方法,傳入修飾符的整數(shù)編碼,以字符串的形式將修飾符返回
代碼如下:
public class ReflectTest05 { public static void main(String[] args) throws Exception{ Class c = Class.forName("java.lang.String"); StringBuffer s = new StringBuffer(); s.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() + "{\n"); Field[] fields = c.getDeclaredFields(); for(Field f:fields){ s.append("\t" + Modifier.toString(f.getModifiers()) + " "+ f.getType().getName()+ " " +f.getName()+"\n"); } s.append("}"); System.out.println(s); } }
編譯結(jié)果如下:
創(chuàng)建一個(gè)User類,如下:
public class User { //四個(gè)Field對(duì)象,分別采用四種不同的訪問權(quán)限修飾符 public int no; private String name; protected int age; boolean sex; }
代碼如下:
public class ReflectTest06 { public static void main(String[] args) throws Exception{ Class c = Class.forName("User"); //通過反射實(shí)例化User類 Object user = c.newInstance(); //設(shè)置User對(duì)象的no Field field = c.getDeclaredField("no"); field.set(user,12); //獲得User對(duì)象的no System.out.println(field.get(user)); //設(shè)置User對(duì)象的name,需要打破封裝,因?yàn)閚ame屬性是私有屬性,不能直接設(shè)置 Field field1 = c.getDeclaredField("name"); field1.setAccessible(true); field1.set(user,"Joke"); System.out.println(field1.get(user)); } }
java.util包下提供了一個(gè)資源綁定器,便于獲取屬性配置文件中的內(nèi)容。
使用以下這種方式的時(shí)候,屬性配置文件xxx.properties必須放到類路徑下。
代碼如下:
public class ResourceBundleTest01 { public static void main(String[] args) { //資源綁定器,只能綁定xxx.properties文件,并且這個(gè)文件必須在類路徑下,文件擴(kuò)展名也必須是properties //并且在寫路徑時(shí),路徑后面的擴(kuò)展名不能寫 ResourceBundle bundle = ResourceBundle.getBundle("classinfo"); String className = bundle.getString("className"); System.out.println(className); } }
首先我們創(chuàng)建一個(gè)屬性配置文件,如下:
className = User
fieldName = name
fieldValue = zhangsan
樣例代碼如下:
public class ReflectTest07 { public static void main(String[] args) throws Exception{ //配合屬性文件使用 ResourceBundle bundle = ResourceBundle.getBundle("classinfo"); Class c2 = Class.forName(bundle.getString("className")); //通過反射實(shí)例化User類 Object obj = c2.newInstance(); Field field1 = c2.getDeclaredField(bundle.getString("fieldName")); //打破封裝 field1.setAccessible(true); field1.set(obj,bundle.getString("fieldValue")); System.out.println(field1.get(obj)); } }
代碼如下:
public class ReflectTest08 { public static void main(String[] args)throws Exception { Class c = Class.forName("java.lang.String"); Method[] methods = c.getDeclaredMethods(); StringBuffer s = new StringBuffer(); for(Method m:methods){ Class[] parameterTypes = m.getParameterTypes(); s.append(Modifier.toString(m.getModifiers()) + " " + m.getReturnType().getSimpleName() + " " + m.getName() + "("); for(Class cs:parameterTypes){ s.append(cs.getSimpleName() + " "); } s.append("){}\n"); } System.out.println(s); } }
編譯結(jié)果:
使用反射機(jī)制調(diào)用一個(gè)對(duì)象的方法,步驟如下:
獲取對(duì)應(yīng)類的Class對(duì)象。
通過反射機(jī)制實(shí)例化出一個(gè)對(duì)象。
通過方法 :public Method getDeclaredMethod(String name, Class... parameterTypes)
,獲取對(duì)應(yīng)的Method對(duì)象
注意:getDeclaredMethod
方法是在java.lang.Class
下的方法,第一個(gè)參數(shù)是方法名,第二個(gè)參數(shù)是可變長(zhǎng)參數(shù),是該方法的形式參數(shù)類型列表
通過方法:public Object invoke(Object obj,Object... args)
,可以調(diào)用Method對(duì)象對(duì)應(yīng)的方法。
注意:該方法是java.lang.reflect.Method
下的方法,第一個(gè)參數(shù)是對(duì)象,第二個(gè)參數(shù)是方法的實(shí)際參數(shù)列表。
往User類中添加方法,如下:
public class User { //四個(gè)Field對(duì)象,分別采用四種不同的訪問權(quán)限修飾符 public int no; private String name; protected int age; boolean sex; public int doSome(int i){ System.out.println("User對(duì)象中的doSome方法執(zhí)行!"); return i; } }
代碼如下:
public class ReflectTest09 { public static void main(String[] args)throws Exception { Class c = Class.forName("User"); Object obj = c.newInstance(); Method method = c.getDeclaredMethod("doSome",int.class); System.out.println(method.invoke(obj,1)); } }
編譯結(jié)果如下:
public class ReflectTest10 { public static void main(String[] args)throws Exception { Class c = Class.forName("java.lang.String"); Constructor[] constructors = c.getDeclaredConstructors(); StringBuffer s = new StringBuffer(); for(Constructor co: constructors){ s.append(Modifier.toString(co.getModifiers()) + " " +c.getSimpleName() + "("); Class[] parameterType = co.getParameterTypes(); for(Class cs:parameterType){ s.append(cs.getSimpleName()+" "); } s.append("){}\n"); } System.out.println(s); } }
編譯結(jié)果如下:
代碼如下:
public class ReflectTest11 { public static void main(String[] args)throws Exception { Class c = Class.forName("User"); //默認(rèn)調(diào)用無參數(shù)構(gòu)造方法 Object obj1 = c.newInstance(); //因?yàn)槊恳粋€(gè)構(gòu)造方法的方法名都一樣,所以getDeclaredConstructor方法的參數(shù)只有要調(diào)用的構(gòu)造方法的構(gòu)造參數(shù)類型列表 Constructor constructor = c.getDeclaredConstructor(int.class,String.class,int.class,boolean.class); Object obj2 = constructor.newInstance(1111,"zhangsan",18,true); System.out.println(obj2); } }
代碼如下:
public class ReflectTest12 { public static void main(String[] args)throws Exception { Class c = Class.forName("java.lang.String"); //一個(gè)類最多只有一個(gè)父類 Class superClass = c.getSuperclass(); System.out.println(superClass.getName()); //一個(gè)類可以實(shí)現(xiàn)多個(gè)接口 Class[] superInterfaces = c.getInterfaces(); for(Class i: superInterfaces){ System.out.println(i.getName()); } } }
編譯結(jié)果如下:
以上就是“Java反射機(jī)制怎么使用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。