技术开发 频道

Java和C++在细节上的差异(二)

  五、反射:

  1. Java的反射机制主要表现为四点:

  1) 在运行中分析类的能力;

  2) 在运行中查看对象;

  3) 实现数组的操作代码;

  4) 利用Method对象,这个对象很像C++中的函数指针。

  注:Java的基于反射的应用主要用于一些工具类库的开发,在实际的应用程序开发中应用的场景较少。

  2. 获取对象的名称(字符串形式) vs 通过对象的名称(字符串形式)创建对象实例,见如下代码:

1     public static void main(String args[]) {
2         //1. 通过对象获取其字符串表示的名称    
3         Date d = new Date();       //or Class<? extends Date> c1 = d.class;
4         Class<? extends Date> c1 = d.getClass();  
5         String className = c1.getName();
6          
7         //2. 通过字符串形式的名称创建类实例。
8         className = "java.util." + className;
9         try {
10             Class c2 = Class.forName(className);
11             //这里用到的newInstance用于创建c2所表示的对象实例,但是必须要求待创建的类实例
12             //具有缺省构造函数(无参数),很明显newInstance调用并未传入任何参数用于构造对象。
13             Date d2 = (Date)c2.newInstance();
14         } catch (ClassNotFoundException e) {
15             e.printStackTrace();
16         } catch (InstantiationException e) {
17             e.printStackTrace();
18         } catch (IllegalAccessException e) {
19             e.printStackTrace();
20         }
21     }

  如果需要通过调用带有参数的构造函数来创建对象实例,需要使用java.lang.reflect.Constructor对象来完成,见如下代码:

1     public static void main(String args[]) {
2         String className = "java.util.Date";
3         try {
4             Class c2 = Class.forName(className);
5             //找到只接受一个long类型参数的构造器
6             Constructor cc = c2.getConstructor(long.class);
7             long ll = 45L;
8             //将该Constructor期望的指定类型(long)的参数实例传入并构造Date对象。
9             Date dd = (Date)cc.newInstance(ll);
10             System.out.println("Date.toString = " + dd);
11         } catch (Exception e) {
12             e.printStackTrace();
13         }
14     }

  3. 遍历一个未知类型的所有域、构造方法和域方法,见如下函数原型:

  Field[] getFields(); 返回指定对象域字段数组,主要包含该类及其超类的所有公有(public)域。

  Field[] getDeclaredFields();返回指定对象域字段数组,主要包含该类自身的所有域,包括private等。

  Method[] getMethods(); 返回指定对象域方法数组,主要包含该类及其超类的所有公有(public)域方法。

  Method[] getDeclaredMethods();返回指定对象域方法数组,主要包含该类自身的所有域方法,包括private等。

  Constructor[] getConstructors(); 返回指定对象构造函数数组,主要包含该类所有公有(public)域构造器。

  Constructor[] getDeclaredConstructors();返回指定对象构造函数数组,主要包含该类所有域构造器。

  int getModifiers(); 返回一个用于描述构造器、方法或域的修饰符的整型数值,使用Modifier类中的静态方法可以协助分析这个返回值。

  String getName(); 返回一个用于描述构造器、方法和域名的字符串。

  Class[] getParameterTypes(); 返回一个用于描述参数类型的Class对象数组。

  Class[] getReturnType(); 返回一个用于描述返回值类型的Class对象。

  1     private static void printConstructors(Class c1) {  
2         Constructor[] constructors = c1.getDeclaredConstructors();  
3         for (Constructor c : constructors) {  
4             String name = c.getName();  
5             System.out.print("    ");  
6             String modifiers = Modifier.toString(c.getModifiers());  
7             if (modifiers.length() > 0)  
8                 System.out.print(modifiers + " ");  
9             System.out.print(name + "(");
10              
11             Class[] paramTypes = c.getParameterTypes();
12             for (int j = 0; j < paramTypes.length; ++j) {
13                 if (j > 0)
14                     System.out.print(",");
15                 System.out.print(paramTypes[j].getName());
16             }
17             System.out.println(");");
18         }
19     }
20      
21     private static void printMethods(Class c1) {
22         Method[] methods = c1.getDeclaredMethods();
23         for (Method m : methods) {
24             Class retType = m.getReturnType();
25             String name = m.getName();
26             System.out.print("    ");
27              
28             String modifiers = Modifier.toString(m.getModifiers());
29             if (modifiers.length() > 0)
30                 System.out.print(modifiers + " ");
31             System.out.print(retType.getName() + " " + name + "(");
32             Class[] paramTypes = m.getParameterTypes();
33             for (int j = 0; j < paramTypes.length; ++j) {
34                 if (j > 0)  
35                     System.out.print(", ");
36                 System.out.print(paramTypes[j].getName());
37             }
38             System.out.println(");");
39         }
40     }
41  
42     private static void printFields(Class c1) {
43         Field[] fields = c1.getDeclaredFields();
44         for (Field f : fields) {
45             Class type = f.getType();
46             String name = f.getName();
47             System.out.print("    ");
48             String modifiers = Modifier.toString(f.getModifiers());
49             if (modifiers.length() > 0)
50                 System.out.print(modifiers + " ");
51             System.out.println(type.getName() + " " + name + ";");
52         }
53     }
54      
55     public static void main(String args[]) {
56         String name = "java.lang.Double";
57         try {
58             Class c1 = Class.forName(name);
59             Class superc1 = c1.getSuperclass();
60             String modifier = Modifier.toString(c1.getModifiers());
61             if (modifier.length() > 0)
62                 System.out.print(modifier + " ");
63              
64             System.out.print("class " + name);
65             if (superc1 != null && superc1 != Object.class)
66                 System.out.print(" extends " + superc1.getName());
67              
68             System.out.print("\n{\n");
69             printConstructors(c1);
70             System.out.println();
71             printMethods(c1);
72             System.out.println();
73             printFields(c1);
74             System.out.println("}");
75         } catch (Exception e) {
76             e.printStackTrace();
77         }
78     }
79     /*    输出结果如下:
80         public final class java.lang.Double extends java.lang.Number
81         {
82             public java.lang.Double(java.lang.String);
83             public java.lang.Double(double);
84          
85             public boolean equals(java.lang.Object);
86             public java.lang.String toString();
87             public static java.lang.String toString(double);
88             public int hashCode();
89             public static native long doubleToRawLongBits(double);
90             public static long doubleToLongBits(double);
91             public static native double longBitsToDouble(long);
92             public int compareTo(java.lang.Double);
93             public volatile int compareTo(java.lang.Object);
94             public byte byteValue();
95             public short shortValue();
96             public int intValue();
97             public long longValue();
98             public float floatValue();
99             public double doubleValue();
100             public static java.lang.Double valueOf(double);
101             public static java.lang.Double valueOf(java.lang.String);
102             public static java.lang.String toHexString(double);
103             public static int compare(double, double);
104             public boolean isNaN();
105             public static boolean isNaN(double);
106             public boolean isInfinite();
107             public static boolean isInfinite(double);
108             public static double parseDouble(java.lang.String);
109        
110             public static final double POSITIVE_INFINITY;
111             public static final double NEGATIVE_INFINITY;
112             public static final double NaN;
113             public static final double MAX_VALUE;
114             public static final double MIN_NORMAL;
115             public static final double MIN_VALUE;
116             public static final int MAX_EXPONENT;
117             public static final int MIN_EXPONENT;
118             public static final int SIZE;
119             public static final java.lang.Class TYPE;
120             private final double value;
121             private static final long serialVersionUID;
122         }
123     */

  

0
相关文章