java的反射java
反射小結數組
Class:是一個類;一個描述類的類安全
Method:是一個描述方法的類;jvm
Filed:是一個描述字段的類;工具
Constructor:是一個描述構造器的類;spa
1.獲得Class對象的三種方法code
2.獲取Method:對象
3.執行Method:blog
4.獲取Field:繼承
5.獲取Field的值:
6.設置Field的值:
7.獲取構造器:
8.經過構造器建立實例
9.反射獲取父類的泛型
10.反射的概述
JAVA反射機制是在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法和屬性,也能夠獲得這個類實現了那些接口;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。
對於每個類而言,JRE都爲其保留了一個不變的Class類形的對象。一個Class對象包含了特定某個類的有關信息。
-class對想只能有系統建立對象
-一個類在jvm中只會有一個Class的實列
-每個類的實例都會記得本身是有哪個Class實力所生成的。
1.1經常使用的工具類
Class類
java的類加載機制
ClassLoader類加載器
Constructor 、Method、Field(字段)
native(本地的)關鍵字,這個是修飾方法是一個原生態的方法,方法的實現不是當前的文件,而是使用其餘的語言實如今文件中。java緣由自己是沒法對系統底層進行訪問和操做的,可是能夠經過JNI接口調用其它的語言來實現對底層的訪問。
2.反射的使用
是用到的類:
Person:
Student:
Person(接口):
Emp(泛型):
1.獲取類的三種方式
經過這三種方法獲取到的Class是同一個,都是相等的.
2.經過Class建立對象
3.獲取對象的全部的方法
/1.獲取類裏面的方法,能夠獲取到接口的,繼承的,可是沒法獲取私有的方法;
/2.獲取到當前這個類的因此的方法,全部聲明的方法,均可以獲取到,且只獲取當前類的方法,也能夠獲取到接口實現的方法,可是不能獲取到繼承的方法
注意,執行一個私有的方法的時候須要跳過安全驗證
1 package reflect; 2 3 import entity.Person; 4 5 import java.lang.reflect.InvocationTargetException; 6 import java.lang.reflect.Method; 7 8 /** 9 *Description:java_project 10 *CreatedbySMO992079on2019/6/1112:48 11 */ 12 public class ReflectGetMetHods{ 13 14 private static Class clazz; 15 16 static{ 17 try{ 18 clazz=Class.forName("entity.Person"); 19 }catch(ClassNotFoundExceptione){ 20 e.printStackTrace(); 21 } 22 } 23 24 public static void testMethod(){ 25 //1.獲取類裏面的方法,能夠獲取到接口的,繼承的,可是沒法獲取私有的方法; 26 Method[] methods = clazz.getMethods(); 27 for(Methodmethod:methods){ 28 System.out.print(" "+method.getName()); 29 } 30 System.out.println(); 31 32 //2.獲取到當前這個類的因此的方法,全部聲明的方法,均可以獲取到,且只獲取當前類的方法,也能夠獲取到接口實現的方法,可是不能獲取到繼承的方法 33 Method[] declaredMethods = clazz.getDeclaredMethods(); 34 for(Method method:declaredMethods){ 35 System.out.print(""+method.getName()); 36 } 37 System.out.println(); 38 39 //3.獲取一個指定的方法,若是有參數的話須要穿一個參數類型例如privatevoidchangeName(Stringname) 40 MethodchangeName=null; 41 try{ 42 //經過getMethod()這個方法是獲取不到私有的方法的。回報java.lang.NoSuchMethodException這個錯誤 43 //changeName=clazz.getMethod("changeName",String.class); 44 changeName=clazz.getDeclaredMethod("changeName",String.class); 45 changeName.setAccessible(true);//私有方法的加必須跳過安全驗證 46 System.out.println(changeName); 47 }catch(NoSuchMethodExceptione){ 48 e.printStackTrace(); 49 } 50 //4.執行一個方法 51 try{ 52 Person o = (Person)clazz.newInstance(); 53 changeName.invoke(o,"張三"); 54 System.out.println(o.getName()); 55 }catch(InstantiationExceptione){ 56 e.printStackTrace(); 57 }catch(IllegalAccessExceptione){ 58 e.printStackTrace(); 59 }catch(InvocationTargetExceptione){ 60 e.printStackTrace(); 61 } 62 63 64 } 65 66 public static void main(String[]args){ 67 testMethod(); 68 } 69 }
4.獲取對象的全部的字段
1 public static void testgetFiled(){ 2 3 //1.獲取本類的全部的字段,可是沒法獲取到父類的字段 4 5 Field[] declaredFields=clazz.getDeclaredFields(); 6 7 for(Fieldfield:declaredFields){ 8 9 System.out.println(field.getName()); 10 11 } 12 13 14 15 //2.獲取指定的字段 16 17 Field name=null; 18 19 try{ 20 21 name=clazz.getDeclaredField("name"); 22 23 System.out.println(name.getName()); 24 25 }catch(NoSuchFieldExceptione){ 26 27 e.printStackTrace(); 28 29 } 30 31 //3.使用字段 32 33 Person person=newPerson("張三",18); 34 35 name.setAccessible(true);//跳過安全驗證 36 37 try{ 38 39 Objecto=name.get(person); 40 41 System.out.println(o); 42 43 }catch(IllegalAccessExceptione){ 44 45 e.printStackTrace(); 46 47 } 48 49 //3.1給一個字段複製 50 51 try{ 52 53 name.set(person,"李四"); 54 55 System.out.println(name.get(person)); 56 57 }catch(IllegalAccessExceptione){ 58 59 e.printStackTrace(); 60 61 } 62 63 }
5.獲取一個類的構造器
1 Public static void testgetConstructors()throws NoSuchMethodException,IllegalAccessException,InvocationTargetException,InstantiationException{ 2 3 //1.獲取本類全部的構造器 4 5 Constructor[] constructors=clazz.getConstructors(); 6 7 for(Constructor constructor :constructors ){ 8 9 System.out.println(constructor); 10 11 } 12 13 //2.獲取指定的構造器 14 15 Constructor<Person>constructor=clazz.getConstructor(); 16 17 18 19 //2.1獲取指定帶參數的構造器 20 21 Constructor<Person>constructor1=clazz.getConstructor(String.class,int.class); 22 23 24 25 //3.經過構造器來建立對象 26 27 Personperson=constructor.newInstance(); 28 29 System.out.println(person); 30 31 32 33 //3.1經過有參數的構造器來建立對象 34 35 Personperson1=constructor1.newInstance("張三",18); 36 37 System.out.println(person1.getName()); 38 39 }
6.獲取父類的泛型
1 public static void testAnnotation(){ 2 3 //獲取帶泛型的子類 4 5 Type type=clazz.getGenericSuperclass(); 6 7 System.out.println(type);//entity.Student<entity.Emp> 8 9 //此時得到了泛型參數,而後就是把它提取出來 10 11 //注意Type是一個空的接口,這裏使用它的子類ParameterizedType,表示帶參數的類類型(即泛型) 12 13 Class clazzs=null; 14 15 if(typeinstanceofParameterizedType){ 16 17 ParameterizedType parameterizedType=(ParameterizedType)type; 18 19 Type[] actualTypeArguments=parameterizedType.getActualTypeArguments(); 20 21 for(Typetypes:actualTypeArguments){ 22 23 System.out.println(types); 24 25 clazzs=(Class<?>)types; 26 27 } 28 29 } 30 31 System.out.println(clazzs); 32 33 }