Java基礎之反射機制(續)

NO IMAGE

回顧

在上篇Java基礎之反射機制,講解了Class實例是反射的源頭,並且講解了獲取Class實例的三種方法:

  • 通過類名獲取
Class clazz= Person.class;
  • 通過對象獲取
Person p=new Person();
Class clazz1=p.getClass();
  • 通過Class類的靜態屬性
Class clazz3=Class.forName("com.zhang.Person");
 System.out.println(clazz3);

那麼我們就可以利用這個Class實例做許多事情。

Class實例的使用

1.創建類的對象

String className="com.zhang.Person";
Class clazz= Class.forName(className);
Person person=(Person) clazz.newInstance();

Person 類需要空參的構造器

空參構造器不能private修飾

2. 獲取類屬性

Class clazz= Person.class;
Field[] fields= clazz.getFields();//只能獲取運行時類及父類聲明為public的屬
for(int i=0;i<fields.length;i++){
  System.out.println(fields[i]);
}

 Field[] fields1 =clazz.getDeclaredFields();//獲取運行時類所有的屬性
for(Field f:fields1){
            System.out.println(f.getName());//獲取屬性名
            System.out.println(f.getModifiers());//獲取權限修飾符
             int i= f.getModifiers();
            System.out.println(Modifier.toString(i));//轉化成對應值
        }

3.獲取類方法

Class clazz= Person.class;
Method[] m1= clazz.getMethods();//獲取運行時類及其父類所有聲明為public的方法
for(Method m:m1){
  System.out.println(m);
}
Method[] m1=clazz.getDeclaredMethods();//獲取類本身聲明的所有方法
      for(Method m:m1){
          System.out.println(m);
           Annotation[] an= m.getAnnotations();//獲取註解
         for (Annotation a:an){
             System.out.println(a);
         }
          Class[] types= m.getParameterTypes();//獲得方法的參數類型
         for(Class type:types){
             System.out.println(type);
         }
         Class re =m.getReturnType();//獲得返回值類型
         System.out.println(re);
         
      Class[] es= m.getExceptionTypes();//獲得異常類型
       for(Class e :es){
           System.out.println(e);
       }
      }

4.獲取構造方法

Class clazz= Person.class;
       Constructor[] cs= clazz.getConstructors();//獲得所有聲明的構造方法
       for (Constructor c:cs){
           System.out.println(c);
       }

5.獲取父類

Class clazz= Person.class;
Class cs=clazz.getSuperclass();//獲取父類
Type type =clazz.getGenericSuperclass();//獲取帶泛型的父類
ParameterizedType param=(ParameterizedType)type;//獲取傳入父類的泛型
Type[] arg1=param.getActualTypeArguments();
System.out.println(((Class)arg1[0]).getName());

6.獲取實現的接口

 Class[] in= clazz.getInterfaces();//獲取接口
for (Class i:in){
    System.out.println(i);
}

7.獲取類所在的包

 Class clazz= Person.class;
System.out.println(clazz.getPackage());

8.獲取類的註解

Class clazz= Person.class;
Annotation[] an=clazz.getAnnotations();

利用反射調用運行時類中指定的方法和屬性

1.調用屬性

Class clazz= Person.class;
Field name=clazz.getField("name");//public權限的
Person p=(Person) clazz.newInstance();
name.set(p,"hello");

 Field age=clazz.getDeclaredField("age");//獲取指定名屬性
age.setAccessible(true);//設置訪問權限
age.set(p,12);
System.out.println(p);

2.調用方法

 Class clazz= Person.class;
Person p=(Person) clazz.newInstance();//實例
Method m1= clazz.getMethod("show");//調用public修飾的方法
m1.invoke(p);//調用

  Class clazz= Person.class;
 Person p=(Person) clazz.newInstance();
  Method m1= clazz.getDeclaredMethod("display", String.class);//調用非public的指定方法
  m1.setAccessible(true);//設置權限
  m1.invoke(p,"china");//調用

3.調用靜態方法

Class clazz= Person.class;
Method m1= clazz.getMethod("show");
m1.invoke(Person.class);//調用靜態方法

4.調用指定的構造器

 Class clazz= Person.class;
Constructor cons= clazz.getDeclaredConstructor(String.class,int.class);
cons.setAccessible(true);
Person p=(Person) cons.newInstance("lily",16);
System.out.println(p);

總結

本篇首先介紹了利用Class實例如何獲取類完整的結構,包括屬性方法構造器註解和父類等等。然後接著介紹了具體利用反射我們如何調用指定的方法構造器和屬性。這樣整個反射的使用就打通了,下一篇講解反射的一個重要應用–動態代理。

喜歡本文的朋友們,歡迎長按下圖關注訂閱號”我的編程筆記”,收看更多精彩內容~~

Java基礎之反射機制(續)

相關文章

換膚功能接入及原理

AndroidBitmap的常用壓縮方式

java未來發展方向!新手入門瞭解

Springcloud(4)熔斷(Hystrix)