java反射技術

來源:互聯網
上載者:User

選擇自 lxblg 的 Blog

java的反射技術功能十分強大,整理一些資料!!

(如需轉載,請註明出處!)

Lesson: 檢測類examing class

1.Retrieving Class Objects
擷取一個Class對象(metadata)

a,從對象的執行個體擷取。
Class c = mystery.getClass();//(return Class)
b,從子類的執行個體擷取
TextField t = new TextField();
Class c = t.getClass();
Class s = c.getSuperclass();
c,知道類名,則可以把.class加入到名字之後來擷取。
Class c = java.awt.Button.class;
d,如果類名在編譯時間是未知的,則可以使用Class.forName()方法來擷取.
Class c = Class.forName(classString);

2.Getting the Class Name
擷取類名稱
 c.getName();

例如:
import java.lang.reflect.*;
import java.awt.*;

class SampleName {

   public static void main(String[] args) {
      Button b = new Button();
      printName(b);
   }

   static void printName(Object o) {
       Class c = o.getClass();
       String s = c.getName();
       System.out.println(s);
   }
}

3.Discovering Class Modifiers
檢索修改符
a.通過getModifiers()方法擷取一個整型標識值。
b.通過java.reflect.Modifier對象的isPublic, isAbstract, 和 isFinal方法判斷此值.

例如:
import java.lang.reflect.*;
import java.awt.*;

class SampleModifier {

   public static void main(String[] args) {
      String s = new String();
      printModifiers(s);
   }

   public static void printModifiers(Object o) {
      Class c = o.getClass();
      int m = c.getModifiers();
      if (Modifier.isPublic(m))
         System.out.println("public");
      if (Modifier.isAbstract(m))
         System.out.println("abstract");
      if (Modifier.isFinal(m))
         System.out.println("final");
   }
}

4.Finding Superclasses
檢索父類
例如:
import java.lang.reflect.*;
import java.awt.*;

class SampleSuper {

   public static void main(String[] args) {
      Button b = new Button();
      printSuperclasses(b);
   }

   static void printSuperclasses(Object o) {
      Class subclass = o.getClass();
      Class superclass = subclass.getSuperclass();
      while (superclass != null) {
         String className = superclass.getName();
         System.out.println(className);
         subclass = superclass;
         superclass = subclass.getSuperclass();
      }
   }
}

5.Identifying the Interfaces Implemented by a Class
檢索指定類實現的介面
例如:
import java.lang.reflect.*;
import java.io.*;

class SampleInterface {

   public static void main(String[] args) {
      try {
          RandomAccessFile r = new RandomAccessFile("myfile", "r");
          printInterfaceNames(r);
      } catch (IOException e) {
          System.out.println(e);
      }
   }

   static void printInterfaceNames(Object o) {
      Class c = o.getClass();
      Class[] theInterfaces = c.getInterfaces();
      for (int i = 0; i < theInterfaces.length; i++) {
         String interfaceName = theInterfaces[i].getName();
         System.out.println(interfaceName);
      }
   }
}
6.Examining Interfaces
判定一個類是不是介面

import java.lang.reflect.*;
import java.util.*;

class SampleCheckInterface {

   public static void main(String[] args) {
      Class thread = Thread.class;
      Class runnable = Runnable.class;
      verifyInterface(thread);
      verifyInterface(runnable);
   }

   static void verifyInterface(Class c) {
      String name = c.getName();
      if (c.isInterface()) {
         System.out.println(name + " is an interface.");
      } else {
         System.out.println(name + " is a class.");
      }
   }
}

 

如:c.isInterface()

7.Identifying Class Fields
找出指定類所有的域成員
每個資料成員可以用java.reflect.Field來封閉其名稱,類型,修改符的集合。
也可以通過相應的方法擷取或設定到該成員的值。
 
如:
import java.lang.reflect.*;
import java.awt.*;

class SampleField {

   public static void main(String[] args) {
      GridBagConstraints g = new GridBagConstraints();
      printFieldNames(g);
   }

   static void printFieldNames(Object o) {
      Class c = o.getClass();
      Field[] publicFields = c.getFields();
      for (int i = 0; i < publicFields.length; i++) {
         String fieldName = publicFields[i].getName();
         Class typeClass = publicFields[i].getType();
         String fieldType = typeClass.getName();
         System.out.println("Name: " + fieldName +
           ", Type: " + fieldType);
         }
      }
}

 

8.Discovering Class Constructors
檢索指定類的建構函式

當建立一個類的執行個體時,是通過檢造方法來作的,這種方法可以被重載。
每一個構造方法可以用類Constructor來描述,,包括名稱,修飾符,參數類型(Class[]),和異常列表。
可以通過一個Class的getConstructors方法擷取到該類的Constructor數組。
常式:
import java.lang.reflect.*;
import java.awt.*;

class SampleConstructor {

   public static void main(String[] args) {
      Rectangle r = new Rectangle();
      showConstructors(r);
   }

   static void showConstructors(Object o) {
      Class c = o.getClass();
      Constructor[] theConstructors = c.getConstructors();
      for (int i = 0; i < theConstructors.length; i++) {
         System.out.print("( ");
         Class[] parameterTypes =
            theConstructors[i].getParameterTypes();
         for (int k = 0; k < parameterTypes.length; k ++) {
            String parameterString = parameterTypes[k].getName();
            System.out.print(parameterString + " ");
            }
         System.out.println(")");
         }
   }
}

 

 

9.Obtaining Method Information
檢索方法
可以找到隸屬於一個類的所有方法,通過getMethods包含Method數組,進而得到該方法的傳回型別,修飾符,方法名稱,參數列表
步驟:
a.指定類的Class Object
b.getMethods()擷取Method[]對象
c,遍曆該數組對象

常式:

import java.lang.reflect.*;
import java.awt.*;

class SampleMethod {

   public static void main(String[] args) {
      Polygon p = new Polygon();
      showMethods(p);
   }

   static void showMethods(Object o) {
      Class c = o.getClass();
      Method[] theMethods = c.getMethods();
      for (int i = 0; i < theMethods.length; i++) {
         String methodString = theMethods[i].getName();
         System.out.println("Name: " + methodString);
         String returnString =
           theMethods[i].getReturnType().getName();
         System.out.println("   Return Type: " + returnString);
         Class[] parameterTypes = theMethods[i].getParameterTypes();
         System.out.print("   Parameter Types:");
         for (int k = 0; k < parameterTypes.length; k ++) {
            String parameterString = parameterTypes[k].getName();
            System.out.print(" " + parameterString);
         }
         System.out.println();
      }
   }
}


Lesson:2 處理對象
1.Creating Objects
一般情況下,建立一個對象用以下方法
Rectangle r = new Rectangle();
但如果你正在開發一個development tools,在運行之前或許不知道要產生對象的類。
所以要像下面這樣來建立對象:
String className;

// . . . load className from the user interface

Object o = new (className); // WRONG!

但以上是錯誤的。
正確的方法是使用類的反射特性:

1)Using No-Argument Constructors
例如:
    Class classDefinition = Class.forName(className);//指定類的運行期執行個體
    object = classDefinition.newInstance();//調用無參建構函式來產生指定類的執行個體。

2)Using Constructors that Have Arguments
這個技術要用到如下步驟:
a,建立一個Class對象
b,建立一個Constructor對象,getConstructor(Class[] params)方法,參數是一個與構造方法相適合的Class 數組.
c,在Constructor對象上調用newInstance方法來產生一個對象,參數 是一個object數組與這個構造方法相配備。

例如:
import java.lang.reflect.*;
import java.awt.*;

class SampleInstance {

   public static void main(String[] args) {

      Rectangle rectangle;
      Class rectangleDefinition;
     

Class[] intArgsClass = new Class[] {int.class, int.class};
      Integer height = new Integer(12);
      Integer width = new Integer(34);
      Object[] intArgs = new Object[] {height, width};

      Constructor intArgsConstructor;

      try {
//1.
        rectangleDefinition = Class.forName("java.awt.Rectangle");
  //2.
      intArgsConstructor =
            rectangleDefinition.getConstructor(intArgsClass);//找到指定的構造方法
//3.     
  rectangle =
            (Rectangle) createObject(intArgsConstructor, intArgs);//構造方法描述對象,object[]
      } catch (ClassNotFoundException e) {
          System.out.println(e);
      } catch (NoSuchMethodException e) {
          System.out.println(e);
      }
   }

   public static Object createObject(Constructor constructor,
                                     Object[] arguments) {

      System.out.println ("Constructor: " + constructor.toString());
      Object object = null;

      try {
        object = constructor.newInstance(arguments);
        System.out.println ("Object: " + object.toString());
        return object;
      } catch (InstantiationException e) {
          System.out.println(e);
      } catch (IllegalAccessException e) {
          System.out.println(e);
      } catch (IllegalArgumentException e) {
          System.out.println(e);
      } catch (InvocationTargetException e) {
          System.out.println(e);
      }
      return object;
   }
}

 

2。Getting Field Values
If you are writing a development tool such as a debugger, you must be able to obtain field values. This is a three-step process:
如果要作一個開發工具像debugger之類的,你必須能發現filed values,以下是三個步驟:
a.建立一個Class對象
b.通過getField 建立一個Field對象
c.調用Field.getXXX(Object)方法(XXX是Int,Float等,如果是對象就省略;Object是指實
例).

例如:
import java.lang.reflect.*;
import java.awt.*;

class SampleGet {

   public static void main(String[] args) {
      Rectangle r = new Rectangle(100, 325);
      printHeight(r);

   }

   static void printHeight(Rectangle r) {
      Field heightField;
      Integer heightValue;
      Class c = r.getClass();
      try {
        heightField = c.getField("height");
        heightValue = (Integer) heightField.get(r);
        System.out.println("Height: " + heightValue.toString());
      } catch (NoSuchFieldException e) {
          System.out.println(e);
      } catch (SecurityException e) {
          System.out.println(e);
      } catch (IllegalAccessException e) {
          System.out.println(e);
      }
   }
}

3。Setting Field Values
a.建立一個Class對象
b.通過getField 建立一個Field對象
c.調用Field.set(Object,withparam)方法(XXX是Int,Float等,如果是對象就省略;Object是指執行個體,withparam指和這個欄位相區配的欄位。

import java.lang.reflect.*;
import java.awt.*;

class SampleSet {

   public static void main(String[] args) {
      Rectangle r = new Rectangle(100, 20);
      System.out.println("original: " + r.toString());
      modifyWidth(r, new Integer(300));
      System.out.println("modified: " + r.toString());
   }

   static void modifyWidth(Rectangle r, Integer widthParam ) {
      Field widthField;
      Integer widthValue;
      Class c = r.getClass();
      try {
        widthField = c.getField("width");
        widthField.set(r, widthParam);
      } catch (NoSuchFieldException e) {
          System.out.println(e);
      } catch (IllegalAccessException e) {
          System.out.println(e);
      }
   }
}

4。調用指定的方法
a.建立一個Class對象
b.建立一個方法對象method,getMethod(String methodName,Class[])方法
c.調方法對象,method.invoke(object,Object[]),兩個參數,第一個是指調用方法所屬於的對象,第二個是傳遞的值對象列表。

The sample program that follows shows you how to invoke a method dynamically. The program retrieves the Method object for the String.concat method and then uses invoke to concatenate two String objects.
//

import java.lang.reflect.*;

class SampleInvoke {

   public static void main(String[] args) {
      String firstWord = "Hello "; //指定類的執行個體

      String secondWord = "everybody.";//變元

      String bothWords = append(firstWord, secondWord);
      System.out.println(bothWords);
   }

   public static String append(String firstWord, String secondWord) {
      String result = null;
      Class c = String.class;
      Class[] parameterTypes = new Class[] {String.class};
      Method concatMethod;
      Object[] arguments = new Object[] {secondWord};
      try {
        concatMethod = c.getMethod("concat", parameterTypes);//擷取到方法對象
        result = (String) concatMethod.invoke(firstWord, arguments);//調用
      } catch (NoSuchMethodException e) {
          System.out.println(e);
      } catch (IllegalAccessException e) {
          System.out.println(e);
      } catch (InvocationTargetException e) {
          System.out.println(e);
      }
      return result;
   }
}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.