iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java通过反射来打印类的方法实现
  • 525
分享到

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

2024-04-02 19:04:59 525人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录一. 案例出发二. 反射方法的分析2.1 反射的方式2.2 修饰符的打印2.3 getDeclaredxxx和getxxx的区别2.4 getSimpleName和getName

工作了有一段时间了,我觉得是时候去复习下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);
    }
}

最终的结果如下:

在这里插入图片描述

二. 反射方法的分析

2.1 反射的方式

代码中我们可以发现,这里提供了两种基本的反射:

  • Class.forName()
  • getClassLoader().loadClass()

首先,在模板类中添加静态块代码:

在这里插入图片描述

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

forName

在这里插入图片描述

getClassLoader

在这里插入图片描述

结论如下:

初始化:通过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 ");

    
    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)    
        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

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

两者区别如下:

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

2.4 getSimpleName和getName有什么不同

以这行代码为例:


String typeName = field.getType().getSimpleName();

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

在这里插入图片描述

可以发现gatName输出的是这个类型的全名称,那么对应的getSimpleName就顾名思义,返回的是类型名称。

对于其他的相关属性和api,代码的注释都写的比较详细了,就不展开介绍了。

到此这篇关于Java通过反射来打印类的方法实现的文章就介绍到这了,更多相关Java反射打印类内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java通过反射来打印类的方法实现

本文链接: https://www.lsjlt.com/news/135982.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作