Java中的反射是怎么回事?

反射的概念

《Java核心技术》中的定义是这样的:能够分析类能力的程序,就是反射

这就是一个概念,跟java中经常提的问题:对象是什么? 一类问题,简单来说就是将类创建对象的逻辑反过来,由对象获得其所属类型的信息。它允许程序在运行时查询和操作类、方法、字段等信息。

实现原理机制

说到反射就不得不谈一个Class类,就是类的类,存的是各种类的状态信息的类,Java的反射机制主要通过java.lang.Class类来实现。你可以通过Class.forName("类名")方法来获取一个Class对象,进而获取该类的信息。

  • Object 类中的getClass( ) 方法将会返回一个Class 类型的实例。
  • Class类常用的方法。
    • e.getname()获取e的类的名字
    • 静态方法Class.forName(className),返回对应的Class对象。
    • 来动态地创建一个类的实例e.getClass().newInstance();

利用反射获取打印类的信息(也叫能力)

不是通过" . "的形式,获得一个类的方法,属性,等具体信息

java 复制代码
package test729;

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

public class ReflectionTest {
    /**
     * 判断程序启动时是否有命令行参数。如果有,则将第一个参数作为类名;如果没有,则提示用户输入类名并读取用户输入。
     * @param args
     */
    public static void main(String[] args) {
        String className;
        if (args.length > 0) {
            className = args[0];
        } else {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入类名(如:java.util.Date):");
            className = scanner.next();
        }
/**
 *使用 Class.forName(className) 动态加载指定的类。然后获取该类的父类和修饰符。
 * 打印类的修饰符、类名和父类信息。
 * 调用 printConstructors(cl), printMethods(cl), 和 printFields(cl) 方法,分别打印构造函数、方法和字段的信息。
 * 捕捉并处理 ClassNotFoundException 异常,打印异常信息。
 */
        try {
            Class<?> cl = Class.forName(className);
            Class<?> superClass = cl.getSuperclass();
            String modifiers = Modifier.toString(cl.getModifiers());

            if (modifiers.length() > 0) {
                System.out.print(modifiers + " ");
            }
            System.out.print("class " + className);
            if (superClass != null && superClass != Object.class) {
                System.out.print(" extends " + superClass.getName());
            }
            System.out.println("\n{");
            printConstructors(cl);
            System.out.println();
            printMethods(cl);
            System.out.println();
            printFields(cl);
            System.out.println("}");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * printConstructors 方法打印类的构造函数信息。
     * 使用 cl.getDeclaredConstructors() 获取所有构造函数。
     * 遍历每个构造函数,获取其修饰符、名称和参数类型。
     * 打印构造函数的修饰符、名称和参数列表。
     * @param cl
     */
    public static void printConstructors(Class<?> cl) {
        Constructor<?>[] constructors = cl.getDeclaredConstructors();
        for (Constructor<?> c : constructors) {
            String name = c.getName();
            String modifiers = Modifier.toString(c.getModifiers());

            System.out.print("  ");
            if (modifiers.length() > 0) {
                System.out.print(modifiers + " ");
            }
            System.out.print(name + "(");

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

    /**
     * printMethods 方法打印类的方法信息。
     * 使用 cl.getDeclaredMethods() 获取所有方法。
     * 遍历每个方法,获取其修饰符、返回类型、名称和参数类型。
     * 打印方法的修饰符、返回类型、名称和参数列表。
     * @param cl
     */
    public static void printMethods(Class<?> cl) {
        Method[] methods = cl.getDeclaredMethods();
        for (Method method : methods) {
            Class<?> returnType = method.getReturnType();
            String name = method.getName();
            String modifiers = Modifier.toString(method.getModifiers());

            System.out.print("  ");
            if (modifiers.length() > 0) {
                System.out.print(modifiers + " ");
            }
            System.out.print(returnType.getName() + " " + name + "(");

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

    /**
     * printFields 方法打印类的字段信息。
     * 使用 cl.getDeclaredFields() 获取所有字段。
     * 遍历每个字段,获取其修饰符、类型和名称。
     * 打印字段的修饰符、类型和名称。
     * 以上代码整体上实现了动态加载类,并输出类的构造函数、方法和字段的信息。
     * @param cl
     */
    public static void printFields(Class<?> cl) {
        Field[] fields = cl.getDeclaredFields();
        for (Field f : fields) {
            Class<?> type = f.getType();
            String name = f.getName();
            String modifiers = Modifier.toString(f.getModifiers());

            System.out.print("  ");
            if (modifiers.length() > 0) {
                System.out.print(modifiers + " ");
            }
            System.out.println(type.getName() + " " + name + ";");
        }
    }
}

这个测试案例可以利用反射打印出一个类的所有信息和属性。

测试输出结果

XML 复制代码
请输入类名(如:java.util.Date):
java.util.Date
public class java.util.Date
{
  public java.util.Date(int, int, int, int, int, int);
  public java.util.Date(java.lang.String);
  public java.util.Date();
  public java.util.Date(long);
  public java.util.Date(int, int, int);
  public java.util.Date(int, int, int, int, int);

  public boolean after(java.util.Date);
  public boolean before(java.util.Date);
  public boolean equals(java.lang.Object);
  public java.lang.String toString();
  public int hashCode();
  public java.lang.Object clone();
  public int compareTo(java.util.Date);
  public volatile int compareTo(java.lang.Object);
  private void readObject(java.io.ObjectInputStream);
  private void writeObject(java.io.ObjectOutputStream);
  private final sun.util.calendar.BaseCalendar$Date normalize(sun.util.calendar.BaseCalendar$Date);
  private final sun.util.calendar.BaseCalendar$Date normalize();
  public static long parse(java.lang.String);
  public static java.util.Date from(java.time.Instant);
  public long getTime();
  public void setTime(long);
  public int getDate();
  public static long UTC(int, int, int, int, int, int);
  private static final java.lang.StringBuilder convertToAbbr(java.lang.StringBuilder, java.lang.String);
  private final sun.util.calendar.BaseCalendar$Date getCalendarDate();
  private static final sun.util.calendar.BaseCalendar getCalendarSystem(int);
  private static final sun.util.calendar.BaseCalendar getCalendarSystem(sun.util.calendar.BaseCalendar$Date);
  private static final sun.util.calendar.BaseCalendar getCalendarSystem(long);
  public int getDay();
  public int getHours();
  private static final synchronized sun.util.calendar.BaseCalendar getJulianCalendar();
  static final long getMillisOf(java.util.Date);
  public int getMinutes();
  public int getMonth();
  public int getSeconds();
  private final long getTimeImpl();
  public int getTimezoneOffset();
  public int getYear();
  public void setDate(int);
  public void setHours(int);
  public void setMinutes(int);
  public void setMonth(int);
  public void setSeconds(int);
  public void setYear(int);
  public java.lang.String toGMTString();
  public java.time.Instant toInstant();
  public java.lang.String toLocaleString();

  private static final sun.util.calendar.BaseCalendar gcal;
  private static sun.util.calendar.BaseCalendar jcal;
  private transient long fastTime;
  private transient sun.util.calendar.BaseCalendar$Date cdate;
  private static int defaultCenturyStart;
  private static final long serialVersionUID;
  private static final [Ljava.lang.String; wtb;
  private static final [I ttb;
}

进程已结束,退出代码为 0
相关推荐
kinlon.liu7 分钟前
零信任安全架构--持续验证
java·安全·安全架构·mfa·持续验证
鸽芷咕23 分钟前
【Python报错已解决】ModuleNotFoundError: No module named ‘paddle‘
开发语言·python·机器学习·bug·paddle
王哲晓28 分钟前
Linux通过yum安装Docker
java·linux·docker
Jhxbdks33 分钟前
C语言中的一些小知识(二)
c语言·开发语言·笔记
java66666888833 分钟前
如何在Java中实现高效的对象映射:Dozer与MapStruct的比较与优化
java·开发语言
Violet永存33 分钟前
源码分析:LinkedList
java·开发语言
执键行天涯34 分钟前
【经验帖】JAVA中同方法,两次调用Mybatis,一次更新,一次查询,同一事务,第一次修改对第二次的可见性如何
java·数据库·mybatis
代码雕刻家35 分钟前
数据结构-3.1.栈的基本概念
c语言·开发语言·数据结构
Fan_web37 分钟前
JavaScript高级——闭包应用-自定义js模块
开发语言·前端·javascript·css·html
梦想科研社42 分钟前
【无人机设计与控制】四旋翼无人机俯仰姿态保持模糊PID控制(带说明报告)
开发语言·算法·数学建模·matlab·无人机