首页 > 代码库 > Java面向对象程序设计--Java反射机制

Java面向对象程序设计--Java反射机制

能够分析类的功能的程序称为反射程序,反射机制的功能相当强大,几个基本的应用是:

  • 在运行时分析各种类的功能;
  • 在运行时对对象进行分析...
  • 实现繁星数组操作的代码
  • 使用Method方法就像使用C++中的函数指针一样;
 1. Class 类:

 

当程序运行时,Java运行时系统维持一份包含每个对象运行时类型标记的信息。这个信息标记了每个对象所属的类型。运行时类型

信息为虚拟机找到正确的函数提供了依据。但这个信息可以通过类的getClass方法得到! 


 1 public class TestReflection 
 2 {
 3     public static void main(String[] args) 
 4     {
 5         Person per = new Person("Bruce Lee");
 6         System.out.println(per.getClass().getName()+" "+per.getName());
 7     }
 8 }
 9 
10 class Person
11 {
12     public Person(String aName)
13     {
14         name = aName;
15     }
16     
17     public String getName()
18     {
19         return name;
20     }
21     
22     private String name;
23 }

 内存中每个Class对象只有唯一的一个:

if(e.getClass() == Employee.class)

这里用==号,而不是equals.

 

Class对象的另外一个重要的用途是在线创建对象:

Class的forName方法和newInstance方法,以及Java的class文件只有在执行时才装载的特性,这几点

位Java在运行时动态执行“未来的”类提供了重要的基础,借助它,你可以方便的实现构件化组装式的应用架构。

可以按照下面这种方式来实现:

1) 主程序中可以不知道构建的具体实现类,而是依据一个配置文件获得构建的具体实现类名;

2) 主程序执行时,从配置文件中读取构建的具体类名,然后用forName的方法和newInstance方法创建类的对象。

 

2. 使用反射机制来分析类的功能:


  1 import java.util.*;
  2 import java.lang.reflect.*;
  3 
  4 public class ReflectionTest 
  5 {
  6     public static void main(String[] args) 
  7     {
  8         // read class name from command line args or user input
  9         String name;
 10         if(args.length > 0) 
 11             name = args[0];
 12         else
 13         {
 14             Scanner in = new Scanner(System.in);
 15             System.out.println("Enter the class name(e.g. java.util.Date): ");
 16             name = in.next();
 17         }
 18         
 19         try
 20         {
 21             //print class name and superclass name
 22             Class cl = Class.forName(name);
 23             Class supercl = cl.getSuperclass();
 24             String modifiers = Modifier.toString(cl.getModifiers());
 25             if(modifiers.length() > 0)
 26                 System.out.print("class "+name);
 27             if(supercl != null && supercl != Object.class)
 28                 System.out.print(" extends "+supercl.getName());
 29             
 30             System.out.print("\n{\n");
 31             printConstructors(cl);
 32             System.out.println();
 33             printMethods(cl);
 34             System.out.println();
 35             printFields(cl);
 36             System.out.println();
 37             System.out.println("}");
 38         }
 39         catch(ClassNotFoundException e)
 40         {
 41             e.printStackTrace();
 42         }
 43         System.exit(0);
 44     }
 45 
 46 /**
 47 * Print all constructors of a class
 48 @param cl a class
 49 */
 50 public static void printConstructors(Class cl)
 51 {
 52     Constructor[] constructors = cl.getDeclaredConstructors();
 53     
 54     for(Constructor c: constructors)
 55     {
 56         String name = c.getName();
 57         System.out.print("   ");
 58         String modifiers = Modifier.toString(c.getModifiers());
 59         if(modifiers.length() > 0) System.out.print(modifiers+" ");
 60         System.out.print(name + "(");
 61         
 62         //print parameter types
 63         Class[] paraTypes = c.getParameterTypes();
 64         for(int j = 0; j < paraTypes.length; j++)
 65         {
 66             if(j > 0) System.out.print(", ");
 67             System.out.print(paraTypes[j].getName());
 68         }
 69         System.out.println(");");
 70     }
 71 }
 72 
 73 /**
 74  * Prints all methods of a class
 75  * @param cl a class
 76  */
 77 public static void printMethods(Class cl)
 78 {
 79     Method[] methods = cl.getDeclaredMethods();
 80     
 81     for(Method m : methods)
 82     {
 83         Class retType = m.getReturnType();
 84         String name = m.getName();
 85         
 86         System.out.print("   ");
 87         //print modifies, return type and method name
 88         String modifiers = Modifier.toString(m.getModifiers());
 89         if(modifiers.length() > 0)
 90             System.out.print(modifiers + " ");
 91         System.out.print(retType + " " + name + "(");
 92         
 93         //print paramrter types
 94         Class[] paramTypes = m.getParameterTypes();
 95         for(int j = 0; j < paramTypes.length; j++)
 96         {
 97             if(j > 0) System.out.print(", ");
 98             System.out.print(paramTypes[j].getName());
 99         }
100         System.out.println(");");
101     }
102 }
103 
104 /**
105  * Prints all fields of a class  
106  * @param cl a class
107  */
108 public static void printFields(Class cl)
109 {
110     Field[] fields = cl.getDeclaredFields();
111     
112     for(Field f : fields)
113     {
114         Class type = f.getType();
115         String name = f.getName();
116         System.out.print("   ");
117         String modifiers = Modifier.toString(f.getModifiers());
118         if(modifiers.length() > 0) 
119             System.out.print(modifiers + " ");
120         System.out.println(type.getName() + " " + name + ";");
121     }
122 }
123 
124 }

 上面这段打印一个类的所有信息:

 1 Enter the class name(e.g. java.util.Date): 
 

 2 class java.util.Date
 3 {
 4    public java.util.Date();
 5    public java.util.Date(long);
 6    public java.util.Date(intintintintint);
 7    public java.util.Date(intintintintintint);
 8    public java.util.Date(java.lang.String);
 9    public java.util.Date(intintint);
10 
11    public long getTime();
12    public void setTime(long);
13    public int getHours();
14    public int getMinutes();
15    public int getMonth();
16    public int getSeconds();
17    public int getYear();
18    public static long UTC(intintintintintint);
19    private static final class java.lang.StringBuilder convertToAbbr(java.lang.StringBuilder, java.lang.String);
20    private final class sun.util.calendar.BaseCalendar$Date getCalendarDate();
21    private static final class sun.util.calendar.BaseCalendar getCalendarSystem(sun.util.calendar.BaseCalendar$Date);
22    private static final class sun.util.calendar.BaseCalendar getCalendarSystem(int);
23    private static final class sun.util.calendar.BaseCalendar getCalendarSystem(long);
24    public int getDay();
25    private static final synchronized class sun.util.calendar.BaseCalendar getJulianCalendar();
26    static final long getMillisOf(java.util.Date);
27    private final long getTimeImpl();
28    public int getTimezoneOffset();
29    public void setDate(int);
30    public void setHours(int);
31    public void setMinutes(int);
32    public void setMonth(int);
33    public void setSeconds(int);
34    public void setYear(int);
35    public class java.lang.String toGMTString();
36    public class java.time.Instant toInstant();
37    public class java.lang.String toLocaleString();
38    public int getDate();
39    public static class java.util.Date from(java.time.Instant);
40    public boolean equals(java.lang.Object);
41    public class java.lang.String toString();
42    public int hashCode();
43    public class java.lang.Object clone();
44    public int compareTo(java.util.Date);
45    public volatile int compareTo(java.lang.Object);
46    private void readObject(java.io.ObjectInputStream);
47    private void writeObject(java.io.ObjectOutputStream);
48    private final class sun.util.calendar.BaseCalendar$Date normalize();
49    private final class sun.util.calendar.BaseCalendar$Date normalize(sun.util.calendar.BaseCalendar$Date);
50    public static long parse(java.lang.String);
51    public boolean after(java.util.Date);
52    public boolean before(java.util.Date);
53 
54    private static final sun.util.calendar.BaseCalendar gcal;
55    private static sun.util.calendar.BaseCalendar jcal;
56    private transient long fastTime;
57    private transient sun.util.calendar.BaseCalendar$Date cdate;
58    private static int defaultCenturyStart;
59    private static final long serialVersionUID;
60    private static final [Ljava.lang.String; wtb;
61    private static final [I ttb;
62 
63 }


 2. 利用反射机制来进行运行时的对象分析:

在程序初始化时就已经设置好的数据域是很好观察的,但反射机制可以观察运行时的数据域信息。