天天看點

Java中的反射(2)——利用反射分析類的基本能力

接着上篇介紹了Class類的一些基本方法之後,我們再來介紹一下反射的基本應用

class Persion{
  public int age;
  private String name;
  public Persion(){

  }
  public Persion(int age,String name){
     this.age=age;
     this.name=name;
  }
  public String getName(){
      return this.name;
  }
}
           

以下的分析都将基于Persion分析

  • 利用反射分析類的能力
    在java.lang.reflect包中有三個類Filed Method和Constructor分别用于描述類的域,方法和構造器。他們都有一個叫做getName的方法,用來傳回項目的名稱。
  • Filed:可以分析一個類的字段
/*輸出cl對象所表示的類或接口所聲明的所有字段。包括公共、保護、預設(包)通路和私有字段,但不包括繼承的字段。*/
public static void printFields(Class cl)
  {
    Field[] fields = cl.getDeclaredFields();
    for (Field f : fields)
     {
       Class type = f.getType();//傳回一個 Class 對象,它辨別了此 Field 對象所表示字段的聲明類型
       String name = f.getName();//傳回此 Field 對象表示的字段的名稱
       System.out.print("   ");
       /*f.getModifiers()以整數形式傳回由此 Field 對象表示的字段的 Java 語言修飾符。*/
       String modifiers = Modifier.toString(f.getModifiers());
       if (modifiers.length() > ) System.out.print(modifiers + " ");         
       System.out.println(type.getName() + " " + name + ";");
      }
   }
           

分析上面的代碼:

Field[] fields = cl.getDeclaredFields();//将會得到Persion類的兩個字段age和name;

  Class type = f.getType();//将會傳回age所屬的類型Integer和name所屬的類型String;

  String name = f.getName();//分别傳回字段名稱:age  name;
           
public class Persion {
    private int age;
    public String name;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Persion(){

    }
    public Persion(int age,String name){
        this.age=age;
        this.name=name;
    }
}
           

以Persion類為例調用此函數:printFields(Date.class)得到的分析結果如下:

private int age;
  public java.lang.String name;
           

Method:可以用來分析一個類的所屬方法

public static void printMethods(Class cl)
   {   
      /*擷取一個類的所有方法*/
      Method[] methods = cl.getDeclaredMethods();

      for (Method m : methods)
      {
         Class retType = m.getReturnType();//擷取此函數的傳回類型
         String name = m.getName();//擷取函數的名字
         System.out.print("   ");
         String modifiers = Modifier.toString(m.getModifiers());//得到方法的通路屬性
         if (modifiers.length() > ) System.out.print(modifiers + " ");         
         System.out.print(retType.getName() + " " + name + "(");
         Class[] paramTypes = m.getParameterTypes();//獲得函數的參數集
         for (int j = ; j < paramTypes.length; j++)
         {
            if (j > ) System.out.print(", ");
            System.out.print(paramTypes[j].getName());
         }
         System.out.println(");");
      }
   }
           

同樣以Persion為例,printMethods(Persion.class)得到的分析結果如下

public java.lang.String getName();
   public void setName(java.lang.String);
   public void setAge(int);
   public int getAge();
           

Constructor:用來分析一個類的構造函數的情況

public static void printConstructors(Class cl)
   {

      Constructor[] constructors = cl.getDeclaredConstructors(); //擷取一個類的所有構造函數集

       /*循環分析每一個構造函數*/
      for (Constructor c : constructors)
      {
         String name = c.getName();//得到構造函數的名字
         System.out.print("   ");
         String modifiers = Modifier.toString(c.getModifiers());
         if (modifiers.length() > ) System.out.print(modifiers + " ");         
         System.out.print(name + "(");

         // 得到構造函數的參數集
         Class[] paramTypes = c.getParameterTypes();
         for (int j = ; j < paramTypes.length; j++)
         {
            if (j > ) System.out.print(", ");
            System.out.print(paramTypes[j].getName());
         }
         System.out.println(");");
      }
   }
           

以Persion為例,printConstructors(persion.class)得到的分析結果如下:

public test.Persion(int, java.lang.String);
   public test.Persion();