Java通过反射来打印类的方法实现

目录

  • 一. 案例出发
  • 二. 反射方法的分析
    • 2.1 反射的方式
    • 2.2 修饰符的打印
    • 2.3 getDeclaredxxx和getxxx的区别
    • 2.4 getSimpleName和getName有什么不同
工作了有一段时间了,我觉得是时候去复习下Java的一些基础知识,因此写下了这篇文章。平常开发过程中,前端写的比较多,后端也不能忘!

【Java通过反射来打印类的方法实现】Java通过反射来打印类的方法实现
文章图片


一. 案例出发 先准备一个模板类:
public class User {public int id; private String name; public User(String name, int id) {this.id = id; this.name = name; }private User(String name) {this.name = name; }public int getId() {return id; }public void setId(int id) {this.id = id; }public String getName() {return name; }public void setName(String name) {this.name = name; }}

开始反射
import java.lang.reflect.*; public class Test {public static final String LINE = "\n"; public static final String SPACE = ""; public static void main(String[] args) throws Exception {Class c = Class.forName("com.User"); // Class c = Test.class.getClassLoader().loadClass("com.User"); StringBuilder sb = new StringBuilder(); // 打印包,类名String packageName = c.getPackage().getName(); sb.append("package " + packageName + "; " + LINE); sb.append(LINE); sb.append("public class " + c.getSimpleName() + "{" + LINE); // 打印成员变量Field[] declaredFields = c.getDeclaredFields(); for (Field field : declaredFields) {// Field.getModifiers()返回一个int类型的数值,用于标识public、static等标识符String fieldModifier = Modifier.toString(field.getModifiers()); // 获取属性类型的简要名称String typeName = field.getType().getSimpleName(); // 属性的名称String fieldName = field.getName(); sb.append(SPACE + fieldModifier + " " + typeName + " " + fieldName + "; " + LINE); }sb.append(LINE); // 打印构造Constructor[] declaredConstructors = c.getDeclaredConstructors(); for (Constructor constructor : declaredConstructors) {// 构造函数的标识符String constructorModifier = Modifier.toString(constructor.getModifiers()); sb.append(SPACE + constructorModifier + " " + c.getSimpleName() + " " + "("); // 打印构造函数的参数printParam(sb, constructor.getParameterTypes()); }// 打印方法Method[] methods = c.getDeclaredMethods(); for (Method method : methods) {// 方法的标识符String methodModifier = Modifier.toString(method.getModifiers()); // 方法返回类型String returnTypeName = method.getReturnType().getSimpleName(); // 方法名称String methodName = method.getName(); sb.append(SPACE + methodModifier + " " + returnTypeName + " " + methodName + "("); printParam(sb, method.getParameterTypes()); }sb.append("}"); System.out.println(sb.toString()); }private static void printParam(StringBuilder sb, Class[] parameterTypes2) {Class[] parameterTypes = parameterTypes2; for (int i = 0; i < parameterTypes.length; i++) {// 参数的类型String simpleName = parameterTypes[i].getSimpleName(); if (i == 0) {sb.append(simpleName + " args"); } else {sb.append(", " + simpleName + " args"); }}sb.append(") {" + LINE); sb.append(SPACE + "}" + LINE); sb.append(LINE); }}

最终的结果如下:

Java通过反射来打印类的方法实现
文章图片


二. 反射方法的分析
2.1 反射的方式
代码中我们可以发现,这里提供了两种基本的反射:
  • Class.forName()
  • getClassLoader().loadClass()
首先,在模板类中添加静态块代码:

Java通过反射来打印类的方法实现
文章图片


再来运行一下两种反射方式的代码:
forName

Java通过反射来打印类的方法实现
文章图片

getClassLoader

Java通过反射来打印类的方法实现
文章图片


结论如下:
初始化:通过forName方式反射的对象,会进行初始化(会执行静态代码),而通过getClassLoader方式反射的对象,是不会进行初始化的。

2.2 修饰符的打印
如果想打印方法、属性的修饰符,我们应该通过Modifier类去拿到。请看这一行代码:
String fieldModifier = Modifier.toString(field.getModifiers());

来看下Modifier.toString的源码:
public static String toString(int mod) {StringBuilder sb = new StringBuilder(); int len; if ((mod & PUBLIC) != 0)sb.append("public "); if ((mod & PROTECTED) != 0)sb.append("protected "); if ((mod & PRIVATE) != 0)sb.append("private "); /* Canonical order */if ((mod & ABSTRACT) != 0)sb.append("abstract "); if ((mod & STATIC) != 0)sb.append("static "); if ((mod & FINAL) != 0)sb.append("final "); if ((mod & TRANSIENT) != 0)sb.append("transient "); if ((mod & VOLATILE) != 0)sb.append("volatile "); if ((mod & SYNCHRONIZED) != 0)sb.append("synchronized "); if ((mod & NATIVE) != 0)sb.append("native "); if ((mod & STRICT) != 0)sb.append("strictfp "); if ((mod & INTERFACE) != 0)sb.append("interface "); if ((len = sb.length()) > 0)/* trim trailing space */return sb.toString().substring(0, len-1); return ""; }

很明显,其通过语言修饰符的类型(int类型)来做对应的映射并返回。
案例代码中有三块地方都支持获得修饰符类型:
  • field.getModifiers():字段修饰符。
  • constructor.getModifiers():构造修饰符。
  • method.getModifiers():方法的修饰符。

2.3 getDeclaredxxx和getxxx的区别
以Field为例:
Field[] declaredFields = c.getDeclaredFields(); Field[] fields = c.getFields();

案例如下:
1.新建一个Parent类:
public class Parent {public String parentAddress; private Integer Number; }

2.让User类继承Parent

Java通过反射来打印类的方法实现
文章图片


3.测试1:getDeclaredFields打印成员变量:

Java通过反射来打印类的方法实现
文章图片

4.测试2:getFields打印成员变量:

Java通过反射来打印类的方法实现
文章图片


两者区别如下:

比较内容 getDeclaredFields getFields
作用的类的范围 仅仅限于当前类 还可以包括父类
作用的修饰符范围 可以获取public和非public类型 只能获得public类型的相关值


2.4 getSimpleName和getName有什么不同
以这行代码为例:
String typeName = field.getType().getSimpleName();

若我将getSimpleName改为getName,看看输出结果会有什么不同:

Java通过反射来打印类的方法实现
文章图片


可以发现gatName输出的是这个类型的全名称,那么对应的getSimpleName就顾名思义,返回的是类型名称。
对于其他的相关属性和API,代码的注释都写的比较详细了,就不展开介绍了。
到此这篇关于Java通过反射来打印类的方法实现的文章就介绍到这了,更多相关Java反射打印类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    推荐阅读