Java 技术之反射

关于Java反射机制的文章很多,这次换种方式来讲解反射的作用。

本文涉及到的知识点:class.getDeclaredXXX()XXX.getModifiers()method.getReturnType()method.getParameterTypes()method.isAnnotationPresent(XXX.class)Modifier.isStatic(method.getModifiers())constructor.newInstance(XX)

本文涉及代码:
https://github.com/wingjay/HelloJava/blob/master/data-structure/src/reflection/ForArticle.java

先来看一个熟悉的 Class

首先,简单来说,反射就是在运行时可以获取任意 ClassObject 内部所有成员属性,如成员变量、成员方法、构造函数和 Annotation。

这次先给出一个大家非常熟悉的 ClassUserBean

本文要完成的任务就是,在只有一个 UserBean.getClass() 的情况下,利用代码打印出其内部所有成员变量、方法,并动态执行内部用 @Invoke 修饰的成员方法

  • package com.wingjay.reflection;
  • public class UserBean {
  • public String userName;
  • private long userId;
  • public UserBean(String userName, long userId) {
  • this.userName = userName;
  • this.userId = userId;
  • }
  • public String getName() {
  • return userName;
  • }
  • public long getId() {
  • return userId;
  • }
  • @Invoke
  • public static void staticMethod(String devName) {
  • System.out.printf("Hi %s, I'm a static method", devName);
  • }
  • @Invoke
  • public void publicMethod() {
  • System.out.println("I'm a public method");
  • }
  • @Invoke
  • private void privateMethod() {
  • System.out.println("I'm a private method");
  • }
  • }

在只提供一个 UserBean 的 Class 情况下,

  1. 打印出这个 Class 内部的所有成员变量、成员方法、构造函数,包括 private 的;
  2. 调用这个 Class 内部的三个用 @Invoke 修饰的方法:staticMethod(), publicMethod(), privateMethod()

1. 打印 UserBean Class 里的所有成员变量、成员方法,包括 private 的

首先我们拥有一个 Class userBeanClass = UserBean.class,我们要利用这个 Class 来打印它的成员变量 userNameuserId

打印成员变量

那么如何获取成员变量呢,我们发现,Java 里提供了 Field 这个类来表示成员变量,提供了 clazz.getDeclaredFields() 来获取一个类内部声明的所有变量。因此,可以利用下面的代码获取 userBeanClass 内部所有的成员变量。

  • Field[] fields = userBeanClass.getDeclaredFields();

那么,我们如何将一个 field 对象打印成 private String userName; 这种形式呢?或者说如何分别找到 privateStringuserName 这三个值呢?

其实,Field 里包含了三种元素来对应它们,分别是ModifierTypeName

  • private <-- field.getModifiers();
  • String <-- field.getType();
  • userName <-- field.getName();
  • // fields
  • Field[] fields = userBeanClass.getDeclaredFields();
  • for(Field field : fields) {
  • String fieldString = "";
  • fieldString += Modifier.toString(field.getModifiers()) + " "; // `private`
  • fieldString += field.getType().getSimpleName() + " "; // `String`
  • fieldString += field.getName(); // `userName`
  • fieldString += ";";
  • System.out.println(fieldString);
  • }

打印结果:

  • public String userName;
  • private long userId;

打印成员方法

类似成员变量的 Field,成员方法也有对应的类 Method,首先可以通过 Method[] methods = userBeanClass.getDeclaredMethods(); 获得所有的成员方法,然后,为了打印形如:public static void staticMethod(String devName)的数据,可以利用下列 method 提供的方法:

```
private static <-- method.getModifiers();
void <-- method.getReturnType();
staticMethod <-- method.getName();

top Created with Sketch.