Java基础——深入浅出Java反射机制(Reflective)

概要

反射是指能够分析类能力的程序,也称为程序运行时的自省能力,主要用于工具程序的构造,而非应用程序。
反射机制的作用包括以下四点:

  1. 运行时分析类
  2. 运行时查看对象
  3. 实现通用数组操作
  4. 利用Method

Java的反射机制主要通过以下几个类实现:Class、Constructor

相关类、方法

Class

Class(代表类型的类,实际是一个泛型类,但平时使用时可忽略类型参数,直接使用原始Class类):如何获得Class对象呢?可通过任意Java类型(或void)的class方法获取,或者是通过对象的getClass方法获得。

常用方法包括:

  1. getName
  2. forName-静态工厂方法,获得指定类名对应的Class对象
  3. newInstance-获得Class表示类型的对象
  4. getFields、getMethods、getConstructor(公有域或方法)
  5. getDeclaredFie1ds、getDeclareMethods、getDeclaredConstructors(全部域或方法,但不包括继承而来的)

Field、Method、Constructor

通用方法

  1. getName
  2. getModifiers–Modifier.toString
  3. setAccessible–可在运行时修改成员的访问限制

Field

  1. getType
  2. get、set

Method

  1. invoke

《Java核心技术-卷一》中应用的典型事例是使用反射机制实现解析打印类的成员。代码示例如下:

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;

/**
 * @description: this program uses reflection to print all features of a class
 * @author: lyg89
 * @create: 2019-03-23 23:10
 **/
public class ReflectionTest {

    public static void main(String[] args) {
        String name;
        if (args.length > 0) {
            name = args[0];
        } else {
            Scanner scanner = new Scanner(System.in);
            System.out.println("Enter class name (e.g. java.util.Date):");
            name = scanner.next();
        }

        try {
            Class<?> aClass = Class.forName(name);
            String modifiers = Modifier.toString(aClass.getModifiers());
            if (modifiers.length() > 0) {
                System.out.print(modifiers + " ");
            }
            System.out.print("class " + name);

            Class<?> superclass = aClass.getSuperclass();
            if (superclass != null && superclass != Object.class) {
                System.out.print(" extends " + superclass.getName());
            }

            System.out.print("\n{\n");
            printConstructors(aClass);
            System.out.println();
            printMethods(aClass);
            System.out.println();
            printFields(aClass);
            System.out.println("}");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.exit(0);
    }

    private static void printConstructors(Class clazz) {

        Constructor[] constructors = clazz.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.print("    ");
            int modifiers = constructor.getModifiers();
            String strModifier = Modifier.toString(modifiers);
            if (strModifier.length() > 0) {
                System.out.print(strModifier + " ");
            }
            System.out.print(clazz.getName() + " (");

            Class[] parameterTypes = constructor.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++) {
                if (i > 0) {
                    System.out.print(", ");
                }
                System.out.print(parameterTypes[i].getName());
            }
            System.out.println(");");
        }
    }

    private static void printMethods(Class clazz) {
        for (Method method : clazz.getMethods()) {
            System.out.print("    ");
            int modifiers = method.getModifiers();
            String strModifier = Modifier.toString(modifiers);
            if (strModifier.length() > 0) {
                System.out.print(strModifier + " ");
            }

            Class<?> returnType = method.getReturnType();
            System.out.print(returnType.getName() + " " + method.getName() + " (");

            Class<?>[] parameterTypes = method.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++) {
                if (i > 0) {
                    System.out.print(", ");
                }
                System.out.print(parameterTypes[i].getName());
            }
            System.out.println(");");
        }
    }

    private static void printFields(Class clazz) {
        for (Field field : clazz.getFields()) {
            System.out.print("    ");
            int modifiers = field.getModifiers();
            String strModifier = Modifier.toString(modifiers);
            if (strModifier.length() > 0) {
                System.out.print(strModifier + " ");
            }
            System.out.println(field.getType().getName() + " " + field.getName() + ";");
        }
    }
}

小结

反射机制帮助我们在程序运行时可以访问程序的元信息,包括Java类型、对象、方法等,并可以动态的创建对象,甚至修改对象的访问控制限制,但是在Java 9中的模块机制,开始对setAccessible有一些限制。利用反射机制,我们可以构造强大的工具集,因此在很多框架中都有应用,可以说理解了反射,对程序的设计所追求的灵活性会有更深刻的认识。

发布了159 篇原创文章 · 获赞 225 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/lyg673770712/article/details/88937414