黑马程序员_反射
-------?android培訓(xùn)、java培訓(xùn)、期待與您交流! ----------
反射的概念:
??? 反射就是把Java類中的各種成分映射想成Java類。通過class文件的對象,獲取構(gòu)造函數(shù)、字段、方法的操作。
??? 例如:眾多的人用一個Person類表示,那么眾多的Java類就用一個Class類表示。
??? 反射也稱之為對類的解剖。把類的各個組成部分映射成一個個相應(yīng)的Java類。
學(xué)習(xí)反射的目的:
??? 有些時候,可能JDK中的方法沒有在幫助文檔中提供,但是通過查看源代碼,卻發(fā)現(xiàn)有這個方法,不會該方法為private私有,所
??? 以JDK的幫助文檔沒有提供該方法。如果必須使用這個方法,我們可以通過反射的方式來獲取,進行使用。
得到某個class文件相對應(yīng)的class對象的方法有3中:
??? 1、getClass():返回進行時的類。
?????? 例如:new Date().getClass()。
??? 2、數(shù)據(jù)類型.class:靜態(tài)屬性,來獲取當(dāng)前數(shù)據(jù)類型的自解碼文件對象。
?????? 例如:Person.class.
??? 3、public static Class forName(String className):返回與帶有給定字符串名的類或接口相關(guān)聯(lián)的Class對象。
?????? 例如:Class.forName("java.long.String");
代碼示例:
public class ClassTest {public static void main(String[] args) throws ClassNotFoundException {String s = "黑馬";//數(shù)據(jù)類型.class:靜態(tài)屬性,來獲取當(dāng)前數(shù)據(jù)類型的自解碼文件對象,Class c1 = String.class;//getClass():返回進行時的類,Class c2 = s.getClass();//Class.forName(String className)返回與帶有給定字符串名的類或接口相關(guān)聯(lián)的Class對象。Class c3 = Class.forName("java.lang.String");System.out.println(c1 == c2);System.out.println(c2 == c3);} }
注意:字節(jié)碼文件是唯一的,無論怎么獲取,都是同一份字節(jié)碼文件。
public class Person {private String name;int age;public String address;public Person(){}private Person(String name){this.name = name;}Person(String name, int age){this.name = name;this.age = age;}public Person(String name, int age, String address){this.name = name;this.age = age;this.address = address;}public void show(){System.out.println("show");}public void method(String s){System.out.println(s);}public String function(){return "function";}public int sum (int x, int y) {return x+y;}private void method(){System.out.println("私有的method");}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + ", address=" + address+ "]";} }構(gòu)造方法的反射應(yīng)用(Constructor類):
??? Constructor類的實例化對象代表類的一個構(gòu)造方法。
??? public Constructor[] getCOnstructors():反射所有的公共的構(gòu)造方法
??? public Constructor[] getDeclaredConstructors():獲取所有的構(gòu)造函數(shù)(包含私有)
??? public Constructor getContructor(Class<?>... parameterTypes):獲取指定的構(gòu)造函數(shù)
??? public Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):獲取指定的構(gòu)造函數(shù)(包含私有)
???
??? public void setAccessible(boolean flag):是否可以訪問(暴力訪問)
??? public Object newInstance(Object... initargs):使用此Constructor對象表示的構(gòu)造方法來創(chuàng)建該構(gòu)造方法的聲明類的新實例,并用于指定的初始化該實例。
步驟:
??? a:創(chuàng)建一個Class字節(jié)碼文件對象
??? b:獲取指定的構(gòu)造函數(shù)? 如果是非public的構(gòu)造函數(shù),需要 強制訪問(暴力訪問)
??? c:創(chuàng)建對象
??? 例如:
import java.lang.reflect.Constructor;public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException {//獲取Person類的字節(jié)碼文件對象Class c = Class.forName("com.itheima_02.Person");//public Constructor[] getConstructors() Constructor[] cons = c.getConstructors();for(Constructor con : cons){System.out.println(con);}System.out.println("-----------------");Constructor[] cons1 = c.getDeclaredConstructors();for(Constructor con : cons1){System.out.println(con);}} }??? 其結(jié)果為:
?? ? ? ?
??? 由結(jié)果可知:public Constructor[] getCOnstructors():反射所有的公共的構(gòu)造方法?? public Constructor[] getDeclaredConstructors():獲取所有的構(gòu)造函數(shù)(包含私有)
成員變量的反射(Field類):
??? Class中的方法:
?? ??? ?public Field[] getFields() : 獲取 public 修飾的 所有字段
?? ??? ?public Field[] getDeclaredFields(): 獲取所有的字段(包含私有)
?? ? ?
?? ??? ?public Field getField(String name): 獲取指定的字段
?? ??? ?public Field getDeclaredField(String name): 獲取指定的字段(包含私有)
?? ?Field中的方法:
??? ??? ?public void set(Object obj, Object value):? 為指定對象中的當(dāng)前字段, 賦值
??? 步驟:
?? ??? ? a: 創(chuàng)建class字節(jié)碼文件對象
?? ??? ? b: 獲取指定的字段,如果是非public 修飾的字段, 需要 暴力訪問
?? ??? ? c: 對字段進行操作
??? 舉例驗證上述方法:
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException;public class ReflectDemo {public static void main(String[] args) throws <span style="font-size:14px;"><span style="font-family:Simsun;"><span style="font-size:14px;"><span style="font-family:Simsun;"><span style="color:#330033;"><span style="LINE-HEIGHT: 21px"></span></span></span></span></span></span>Exception<span style="font-size:14px;"><span style="font-family:Simsun;"><span style="font-size:14px;"><span style="font-family:Simsun;"><span style="color:#330033;"><span style="LINE-HEIGHT: 21px"></span></span></span></span></span></span> {// 創(chuàng)建class字節(jié)碼文件對象Class c = Class.forName("com.itheima_02.Person");//創(chuàng)建構(gòu)造函數(shù)并創(chuàng)建對象Constructor con = c.getDeclaredConstructor();Object obj = con.newInstance();// Person//public Field[] getFields()Field[] fields = c.getFields();for (Field field : fields) {System.out.println(field);}System.out.println("-------");//public Field[] getDeclaredFields()Field[] fields1 = c.getDeclaredFields();for (Field field : fields1) {System.out.println(field);}//public Field getField(String name): 獲取指定的字段Field addressField = c.getField("address");System.out.println(obj);//public void set(Object obj, Object value): 為指定對象中的當(dāng)前字段, 賦值addressField.set(obj, "北京");//private String name;Field nameField = c.getDeclaredField("name");nameField.setAccessible(true);//暴力訪問nameField.set(obj, "黑馬");System.out.println(obj);} } ??? 其結(jié)果為:
???????
?? ??? ?public Method[] getMethods() 獲取所有的公共方法(包含父類的)
?? ??? ?public Method[] getDeclaredMethods() 獲取所有的方法(不包含父類)
?? ??? ?public Method getMethod(String name, Class<?>... parameterTypes) : 獲取指定的方法
?? ??? ?public Method getDeclaredMethod(String name, Class<?>... parameterTypes) : 獲取指定的方法(包含私有的)
?? ?Method類的方法:
? ?? ??? ?public Object invoke(Object obj, Object... args)
? ?? ??? ?調(diào)用給定的對象中的當(dāng)前方法,并且給定方法的參數(shù)列表,這個時候就可以確定調(diào)用的是具體的哪一個方法了
? ?? ??? ?public void setAccessible(boolean flag)
??? 步驟:
?? ??? ?a: 創(chuàng)建class 字節(jié)碼文件對象
?? ??? ?b: 獲取指定的方法
?? ??? ?c: 使用方法(需要前有對象,才能使用方法)
??? ? 舉例驗證上述方法:
??? import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;public class ReflectDemo2 {public static void main(String[] args) throws Exception {//創(chuàng)建class 字節(jié)碼文件對象Class c = Class.forName("com.itheima_02.Person");//public Method[] getMethods() publicMethod[] methods = c.getMethods();for (Method method : methods) {System.out.println(method);}System.out.println("--------");//public Method[] getDeclaredMethods() 所有的Method[] methods1 = c.getDeclaredMethods();for (Method method : methods1) {System.out.println(method);}/** Person p = new Person();* p.show();*/Constructor con = c.getConstructor();Object obj = con.newInstance();// Person//獲取指定的方法//public Method getMethod(String name, Class<?>... parameterTypes) : 獲取指定的方法Method showMethod = c.getMethod("show",null); //System.out.println(showMethod);//使用方法//public Object invoke(Object obj, Object... args)//調(diào)用給定的對象中的當(dāng)前方法,并且給定方法的參數(shù)列表,這個時候就可以確定調(diào)用的是具體的哪一個方法了showMethod.invoke(obj, null);System.out.println("-----------------------------------------");//public void method(String s){}//public Method getMethod(String name, Class<?>... parameterTypes) : 獲取指定的方法Method meMethod = c.getMethod("method", String.class);//public Object invoke(Object obj, Object... args)meMethod.invoke(obj, "黑馬");System.out.println("-----------------------------------------");//public String function(){}Method functionMethod = c.getMethod("function", null);String str = (String) functionMethod.invoke(obj,null);System.out.println(str);System.out.println("-----------------------------------------");//public int sum (int x, int y) {}Method sumMethod = c.getMethod("sum", int.class, int.class);int sum = (int) sumMethod.invoke(obj, 22, 11);System.out.println(sum);System.out.println("-----------------------------------------");//private void method(){}//Method me2Method = c.getMethod("method", null);Method me2Method = c.getDeclaredMethod("method", null);//暴力點me2Method.setAccessible(true);me2Method.invoke(obj, null);} }??? 其結(jié)果為:
???????
-------?android培訓(xùn)、java培訓(xùn)、期待與您交流! ----------
反射的概念:
??? 反射就是把Java類中的各種成分映射想成Java類。通過class文件的對象,獲取構(gòu)造函數(shù)、字段、方法的操作。
??? 例如:眾多的人用一個Person類表示,那么眾多的Java類就用一個Class類表示。
??? 反射也稱之為對類的解剖。把類的各個組成部分映射成一個個相應(yīng)的Java類。
學(xué)習(xí)反射的目的:
??? 有些時候,可能JDK中的方法沒有在幫助文檔中提供,但是通過查看源代碼,卻發(fā)現(xiàn)有這個方法,不會該方法為private私有,所
??? 以JDK的幫助文檔沒有提供該方法。如果必須使用這個方法,我們可以通過反射的方式來獲取,進行使用。
得到某個class文件相對應(yīng)的class對象的方法有3中:
??? 1、getClass():返回進行時的類。
?????? 例如:new Date().getClass()。
??? 2、數(shù)據(jù)類型.class:靜態(tài)屬性,來獲取當(dāng)前數(shù)據(jù)類型的自解碼文件對象。
?????? 例如:Person.class.
??? 3、public static Class forName(String className):返回與帶有給定字符串名的類或接口相關(guān)聯(lián)的Class對象。
?????? 例如:Class.forName("java.long.String");
代碼示例:
public class ClassTest {public static void main(String[] args) throws ClassNotFoundException {String s = "黑馬";//數(shù)據(jù)類型.class:靜態(tài)屬性,來獲取當(dāng)前數(shù)據(jù)類型的自解碼文件對象,Class c1 = String.class;//getClass():返回進行時的類,Class c2 = s.getClass();//Class.forName(String className)返回與帶有給定字符串名的類或接口相關(guān)聯(lián)的Class對象。Class c3 = Class.forName("java.lang.String");System.out.println(c1 == c2);System.out.println(c2 == c3);} }
注意:字節(jié)碼文件是唯一的,無論怎么獲取,都是同一份字節(jié)碼文件。
public class Person {private String name;int age;public String address;public Person(){}private Person(String name){this.name = name;}Person(String name, int age){this.name = name;this.age = age;}public Person(String name, int age, String address){this.name = name;this.age = age;this.address = address;}public void show(){System.out.println("show");}public void method(String s){System.out.println(s);}public String function(){return "function";}public int sum (int x, int y) {return x+y;}private void method(){System.out.println("私有的method");}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + ", address=" + address+ "]";} }構(gòu)造方法的反射應(yīng)用(Constructor類):
??? Constructor類的實例化對象代表類的一個構(gòu)造方法。
??? public Constructor[] getCOnstructors():反射所有的公共的構(gòu)造方法
??? public Constructor[] getDeclaredConstructors():獲取所有的構(gòu)造函數(shù)(包含私有)
??? public Constructor getContructor(Class<?>... parameterTypes):獲取指定的構(gòu)造函數(shù)
??? public Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):獲取指定的構(gòu)造函數(shù)(包含私有)
???
??? public void setAccessible(boolean flag):是否可以訪問(暴力訪問)
??? public Object newInstance(Object... initargs):使用此Constructor對象表示的構(gòu)造方法來創(chuàng)建該構(gòu)造方法的聲明類的新實例,并用于指定的初始化該實例。
步驟:
??? a:創(chuàng)建一個Class字節(jié)碼文件對象
??? b:獲取指定的構(gòu)造函數(shù)? 如果是非public的構(gòu)造函數(shù),需要 強制訪問(暴力訪問)
??? c:創(chuàng)建對象
??? 例如:
import java.lang.reflect.Constructor;public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException {//獲取Person類的字節(jié)碼文件對象Class c = Class.forName("com.itheima_02.Person");//public Constructor[] getConstructors() Constructor[] cons = c.getConstructors();for(Constructor con : cons){System.out.println(con);}System.out.println("-----------------");Constructor[] cons1 = c.getDeclaredConstructors();for(Constructor con : cons1){System.out.println(con);}} }??? 其結(jié)果為:
?? ? ? ?
??? 由結(jié)果可知:public Constructor[] getCOnstructors():反射所有的公共的構(gòu)造方法?? public Constructor[] getDeclaredConstructors():獲取所有的構(gòu)造函數(shù)(包含私有)
成員變量的反射(Field類):
??? Class中的方法:
?? ??? ?public Field[] getFields() : 獲取 public 修飾的 所有字段
?? ??? ?public Field[] getDeclaredFields(): 獲取所有的字段(包含私有)
?? ? ?
?? ??? ?public Field getField(String name): 獲取指定的字段
?? ??? ?public Field getDeclaredField(String name): 獲取指定的字段(包含私有)
?? ?Field中的方法:
??? ??? ?public void set(Object obj, Object value):? 為指定對象中的當(dāng)前字段, 賦值
??? 步驟:
?? ??? ? a: 創(chuàng)建class字節(jié)碼文件對象
?? ??? ? b: 獲取指定的字段,如果是非public 修飾的字段, 需要 暴力訪問
?? ??? ? c: 對字段進行操作
??? 舉例驗證上述方法:
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException;public class ReflectDemo {public static void main(String[] args) throws <span style="font-size:14px;"><span style="font-family:Simsun;"><span style="font-size:14px;"><span style="font-family:Simsun;"><span style="color:#330033;"><span style="LINE-HEIGHT: 21px"></span></span></span></span></span></span>Exception<span style="font-size:14px;"><span style="font-family:Simsun;"><span style="font-size:14px;"><span style="font-family:Simsun;"><span style="color:#330033;"><span style="LINE-HEIGHT: 21px"></span></span></span></span></span></span> {// 創(chuàng)建class字節(jié)碼文件對象Class c = Class.forName("com.itheima_02.Person");//創(chuàng)建構(gòu)造函數(shù)并創(chuàng)建對象Constructor con = c.getDeclaredConstructor();Object obj = con.newInstance();// Person//public Field[] getFields()Field[] fields = c.getFields();for (Field field : fields) {System.out.println(field);}System.out.println("-------");//public Field[] getDeclaredFields()Field[] fields1 = c.getDeclaredFields();for (Field field : fields1) {System.out.println(field);}//public Field getField(String name): 獲取指定的字段Field addressField = c.getField("address");System.out.println(obj);//public void set(Object obj, Object value): 為指定對象中的當(dāng)前字段, 賦值addressField.set(obj, "北京");//private String name;Field nameField = c.getDeclaredField("name");nameField.setAccessible(true);//暴力訪問nameField.set(obj, "黑馬");System.out.println(obj);} } ??? 其結(jié)果為:
???????
成員方法的反射(Method類):
??? Class類中的方法:?? ??? ?public Method[] getMethods() 獲取所有的公共方法(包含父類的)
?? ??? ?public Method[] getDeclaredMethods() 獲取所有的方法(不包含父類)
?? ??? ?public Method getMethod(String name, Class<?>... parameterTypes) : 獲取指定的方法
?? ??? ?public Method getDeclaredMethod(String name, Class<?>... parameterTypes) : 獲取指定的方法(包含私有的)
?? ?Method類的方法:
? ?? ??? ?public Object invoke(Object obj, Object... args)
? ?? ??? ?調(diào)用給定的對象中的當(dāng)前方法,并且給定方法的參數(shù)列表,這個時候就可以確定調(diào)用的是具體的哪一個方法了
? ?? ??? ?public void setAccessible(boolean flag)
??? 步驟:
?? ??? ?a: 創(chuàng)建class 字節(jié)碼文件對象
?? ??? ?b: 獲取指定的方法
?? ??? ?c: 使用方法(需要前有對象,才能使用方法)
??? ? 舉例驗證上述方法:
??? import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;public class ReflectDemo2 {public static void main(String[] args) throws Exception {//創(chuàng)建class 字節(jié)碼文件對象Class c = Class.forName("com.itheima_02.Person");//public Method[] getMethods() publicMethod[] methods = c.getMethods();for (Method method : methods) {System.out.println(method);}System.out.println("--------");//public Method[] getDeclaredMethods() 所有的Method[] methods1 = c.getDeclaredMethods();for (Method method : methods1) {System.out.println(method);}/** Person p = new Person();* p.show();*/Constructor con = c.getConstructor();Object obj = con.newInstance();// Person//獲取指定的方法//public Method getMethod(String name, Class<?>... parameterTypes) : 獲取指定的方法Method showMethod = c.getMethod("show",null); //System.out.println(showMethod);//使用方法//public Object invoke(Object obj, Object... args)//調(diào)用給定的對象中的當(dāng)前方法,并且給定方法的參數(shù)列表,這個時候就可以確定調(diào)用的是具體的哪一個方法了showMethod.invoke(obj, null);System.out.println("-----------------------------------------");//public void method(String s){}//public Method getMethod(String name, Class<?>... parameterTypes) : 獲取指定的方法Method meMethod = c.getMethod("method", String.class);//public Object invoke(Object obj, Object... args)meMethod.invoke(obj, "黑馬");System.out.println("-----------------------------------------");//public String function(){}Method functionMethod = c.getMethod("function", null);String str = (String) functionMethod.invoke(obj,null);System.out.println(str);System.out.println("-----------------------------------------");//public int sum (int x, int y) {}Method sumMethod = c.getMethod("sum", int.class, int.class);int sum = (int) sumMethod.invoke(obj, 22, 11);System.out.println(sum);System.out.println("-----------------------------------------");//private void method(){}//Method me2Method = c.getMethod("method", null);Method me2Method = c.getDeclaredMethod("method", null);//暴力點me2Method.setAccessible(true);me2Method.invoke(obj, null);} }??? 其結(jié)果為:
???????
-------?android培訓(xùn)、java培訓(xùn)、期待與您交流! ----------
總結(jié)
- 上一篇: [html] 如何根据设备尺寸做页面自
- 下一篇: [html] HTML为什么要语义化?