Core Java 笔记(五)

反射

作用:

  • 在运行时分析类的能力

  • 在运行时查看对象

  • 实现通用的数组操作代码

  • 利用 Method 对象

一、Class 

在程序运行期间,Java 运行时系统始终为所有对象维护一个运行时(runtime)的类型标识,这个信息跟踪着每个对象所属的类,虚拟机会利用运行时类型信息选择相应的方法执行。Class 类保存了这些信息,可以用 Object 中定义的 getClass 方法得到一个 Class 对象,这个对象表示一个特定类的属性。

用 getName 方法返回类的名字:

Employee e = new Employee("Babara", ...);
System.out.println(e.getClass().getName() + ": " + e.getName());  //  Employee: Babara   

用静态方法 forName 可以获得类名对应的 Class 对象:

String className = "java.util.Random";
Class cl = Class.forName(className);

一个 Class 对象实际上表示的是一个类型(未必是一个类),假设 T 是任意的 Java 类型,则 T.class 代表对应的 Class 对象:

Class cl1 = Random.class;
Class cl2 = int.class;
Class cl3 = Double[].class;
// ...

虚拟机为每个类型管理一个 Class 对象,因此可以利用 == 运算符进行比较:

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

用 newInstance 方法可以动态地创建一个类的实例(如果这个类没有无参数的构造器,则抛出异常):

String str = "java.util.Random";
Object m = Class.forName(str).newInstance();  // m = new Random();  

Class 类实际上是一个泛型类

API - java.lang.Class

  • forName

  • getName

  • newInstance

  • getField
  • getFields / getMethods / getConstructors

  • getDeclareFields / getDeclareMethods / getDeclareConstructors


二、检查类的结构

java.lang.reflect 包中有三个类 Field、Method、Constructor 分别用于描述类的域、方法、构造器,还有 Modifier 用于反映方法或构造器的修饰符。

API - java.lang.reflect.Constructor

  • getDeclaringClass

  • getExceptionTypes

  • getModifiers

  • getName
  • getParameterTypes

  • getReturnType

下面是书中一个测试 demo ,输入类名,能够输出这个类所有域名以及方法和构造器的签名:

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

public class ReflectionTest {
    public static void main(String[] args) {
        // 读取类名
        String name;
        if (args.length > 0) {
            name = args[0];
        } else {
            Scanner in = new Scanner(System.in);
            System.out.println("输入类名(如:java.util.Data):");
            name = in.next();
        }

        // 打印类名和超类名
        try {
            Class cl = Class.forName(name);
            Class supercl = cl.getSuperclass();
            String modifiers = Modifier.toString(cl.getModifiers());
            if (modifiers.length() > 0) {
                System.out.print(modifiers + " ");
            }
            System.out.print("class " + name);
            if (supercl != null && supercl != Object.class) {
                System.out.print(" extends " + supercl.getName());
            }
System.out.print(" {\n"); printFields(cl); System.out.println(); printConstructors(cl); System.out.println(); printMethods(cl); System.out.println(
"}"); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.exit(0); } public static void printFields(Class cl) { Field[] fields = cl.getDeclaredFields(); for (Field f : fields) { Class type = f.getType(); String name = f.getName(); System.out.print("\t"); String modifiers = Modifier.toString(f.getModifiers()); if (modifiers.length() > 0) { System.out.print(modifiers + " "); } System.out.println(type.getName() + " " + name + ";"); } } public static void printConstructors(Class cl) { Constructor[] constructors = cl.getDeclaredConstructors(); for (Constructor c : constructors) { String name = c.getName(); System.out.print("\t"); String modifiers = Modifier.toString(c.getModifiers()); if (modifiers.length() > 0) { System.out.print(modifiers + " "); } System.out.print(name + " "); printParameters(c.getParameterTypes()); } } 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("\t"); String modifiers = Modifier.toString(m.getModifiers()); if (modifiers.length() > 0) { System.out.print(modifiers + " "); } System.out.print(retType.getName() + " " + name); printParameters(m.getParameterTypes()); } } public static void printParameters(Class[] paramTypes) { System.out.print("("); for (int i = 0; i < paramTypes.length; i++) { if (i > 0) { System.out.print(", "); } System.out.print(paramTypes[i].getName()); } System.out.println(");"); } }

运行情况:

猜你喜欢

转载自www.cnblogs.com/zzzt20/p/11460511.html