java中的反射

 

 

java的反射java

 

反射小結數組

Class:是一個類;一個描述類的類安全

Method:是一個描述方法的類;jvm

Filed:是一個描述字段的類;工具

Constructor:是一個描述構造器的類;spa

 

1.獲得Class對象的三種方法code

  • Class clazz = 類名.class;
  • Class clazz = 對項目.getClass();
  • Class clazz = Class.forName("全類名");

 

2.獲取Method:對象

  • getMethods():不能獲取私有的方法,可是能夠獲取到所繼承的方法;
  • getDeclaredMethods():不能獲取到繼承的方法;私有方法要跳過驗證
  • getDeclaredMethod(String methondName,Class … parameterTypes):獲取單個方法,若是有參數則須要傳入參數

3.執行Method:blog

  • 若是調用的方法是私有的話就須要跳過安全驗證setAccessible(true);
  • method.invoke(obj,Object … args);

 

4.獲取Field:繼承

  • getFields():不能獲取私有的字段,可是能夠獲取到所繼承的字段;
  • getDeclaredFields():不能獲取到繼承的字段;私有字段要跳過驗證
  • getDeclaredField(String fieldName):獲取單個字段

5.獲取Field的值:

  • 私有的字段就須要跳過安全檢查setAccessible(true);
  • field.get(obj);

6.設置Field的值:

  • 私有字段跳過安全驗證
  • filed.set(obj,value);
  1.  

7.獲取構造器:

  • getConstructors();獲取全部構造器;
  • getConstructor(Class<?>...parameterTypes);獲取單個構造器(能夠獲取帶參構造器)

8.經過構造器建立實例

  • constructor.newInstance();若是有參數則獲取有參構造器把參數傳入便可
  1.  

9.反射獲取父類的泛型

  • getGenericSuperClass():獲取到帶泛型的父類
  • Type是一個空的接口,是用的時候要使用他的子接口ParameterizedType
  • 調用getActualTypeArguments()返回父類的泛型數組

 

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 }
相關文章
相關標籤/搜索