Java中的反射是怎么回事?

news2024/9/9 1:38:08

反射的概念

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

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

实现原理机制

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

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

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

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

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 + ";");
        }
    }
}

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

测试输出结果

请输入类名(如: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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1959152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

testRigor-基于人工智能驱动的无代码自动化测试平台

1、testRigor介绍 简单来说&#xff0c;testRigor是一款基于人工智能驱动的无代码自动化测试平台&#xff0c;它能够通过分析应用的行为模式&#xff0c;智能地生成测试用例&#xff0c;并自动执行这些测试&#xff0c;无需人工编写测试脚本。可以用于Web、移动、API和本机桌面…

MongoDB 基础知识

一、为什么学习MongoDB MongoDB解决Mysql 的“三高”问题&#xff1a; 1.对数据库高并发写入需求 2.对海量数据高效率存储访问需求 3.对数据库高扩展和高可用的需求 MongoDB 实际应用&#xff1a; 1.社交场景&#xff0c;比如朋友圈&#xff0c;附近的人的地点的存储 2.…

常用七大公司加密软件排行榜|2024年好用高效加密软件最新推荐

加密软件对于保护公司数据和确保信息安全至关重要。本文分享七款公司加密软件&#xff0c;每款软件的功能和优势都有所不同&#xff0c;可以根据企业的具体需求选择合适的解决方案。 1. 固信软件 功能&#xff1a; 固信软件提供全面的数据保护解决方案&#xff0c;透明加密、智…

Java开发者LLM实战——使用LangChain4j构建本地RAG系统

1、引言 由于目前比较火的chatGPT是预训练模型&#xff0c;而训练一个大模型是需要较长时间&#xff08;参数越多学习时间越长&#xff0c;保守估计一般是几个月&#xff0c;不差钱的可以多用点GPU缩短这个时间&#xff09;&#xff0c;这就导致了它所学习的知识不会是最新的&…

Stable Diffusion参数 - 步数、采样方法、提示词引导系数

1 迭代步数 一张图片的生成它需要多次迭代才能达到我们想要的一个效果。 理论上迭代步数越高&#xff0c;那生成的最终的这个图片的效果就越好&#xff0c;它质量更高。 实际在应用的时候迭代步数达到20以上&#xff0c;它的效果在提升的就不是十分明显了&#xff0c;而更多的…

基于python的百度迁徙迁入、迁出数据分析(三)

百度迁徙定义 百度迁徙释义&#xff1a; 百度迁徙以用户常住地所在地市或停留超过一天的非常住地定义为出发城市&#xff0c;以用户离开出发城市&#xff0c;并在非出发城市停留超过4 h以上定义为到达城市。采用4h阈值&#xff0c;排除了城际出行中的途经地。 定义参考来源…

当年很流行,现在已经淘汰的Java技术,请不要学了!【建议收藏】

在Java技术的发展历程中&#xff0c;确实有一些曾经流行但现在已经被淘汰或不再推荐使用的技术。了解这些技术可以帮助你避免学习过时的知识&#xff0c;从而更高效地提升自己的技能。 以下是一些曾经流行但现在已经不太推荐学习的Java技术&#xff1a; 1. Servlet 2.x&#x…

日程管理多源归一,服务场景一键直达

时间对于每个人来说都是非常宝贵的&#xff0c;曾经我们使用台历、挂历来标记和查看重要日程&#xff0c;通过翻页来见证时光的流逝&#xff0c;随着信息化时代的不断发展&#xff0c;更加灵活简洁的电子日历成为主流&#xff0c;日历也从一个最简单的日期看板&#xff0c;慢慢…

RuntimeError: No CUDA GPUs are available

RuntimeError: No CUDA GPUs are available 目录 RuntimeError: No CUDA GPUs are available 【常见模块错误】 【解决方案】 解决步骤如下&#xff1a; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科…

如何利用代理ip探索外国新闻视角?

引言 在日常的网络使用中我们常常会遇到诸多难题&#xff0c;让我们无法获取到想要的信息或服务&#xff0c;若访问速度很慢还会影响好的在线工作和娱乐体验。其次&#xff0c;随着网络安全问题的频发&#xff0c;个人隐私泄露成为了一个不容忽视的问题。这些痛点&#xff0c;…

React Native新架构系列-新架构介绍

从今天起&#xff0c;会陆续更新React Native新架构相关的系列内容&#xff0c;本系列基于React Native 0.73.4版本&#xff0c;从一名Android开发者的视角进行介绍。本系列介绍的内容默认读者对React Native有一定的了解&#xff0c;对基础的开发内容不再赘述。 前言 首先介绍…

AI绘画3分钟解决英文恐惧症,comfyui汉化插件

前言 全面解析&#xff1a;Comfy UI汉化插件的安装与配置指南 本文涉及的工作流和插件&#xff0c;需要的朋友请扫描免费获取哦 引言 本文图片来源网络&#xff0c;侵权联删除。 在全球化的今天&#xff0c;软件界面的本地化是提升用户体验的重要一环。对于许多非英语母语的…

辅听耳机芯片型号介绍—云信通讯

辅听耳机系列芯片介绍&#xff1a; 杰理芯片型号&#xff1a; AC7003D / AC7006F 芯片特点&#xff1a; 1.内置啸叫抑制算法 2.内置辅听专用动态多段增益调节 3.内置人声增强和环境噪声压制算法 4.公版手机app开放定制服务&#xff0c;支持听力测试和个性化增益配置 5.支…

WAAP替代传统WAF已成趋势

数字化时代&#xff0c;Web应用和API已成为企业运营的核心。然而&#xff0c;随着网络攻击手段的不断进化&#xff0c;自动化攻击愈发频繁&#xff0c;传统的Web应用防火墙&#xff08;WAF&#xff09;已难以满足现代企业的安全需求。WAAP&#xff08;Web Application and API …

Springboot手工艺品交易平台—计算机毕业设计源码11541

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对手工艺品交易平台等问题&#xff0c;对手工…

办公人导航-一个资源丰富的网站

办公人导航是一个资源丰富的网站&#xff0c;旨在为办公人员提供各种优质资源和工具&#xff0c;以提高工作效率和生活质量。 ★★★★★办公人导航&#xff1a;https://www.bgrdh.com/ 这个网站涵盖了以下几个方面&#xff1a; 综合性的导航平台&#xff1a;办公人导航集成了…

机械学习—零基础学习日志(高数15——函数极限性质)

零基础为了学人工智能&#xff0c;真的开始复习高数 这里我们将会学习函数极限的性质。 唯一性 来一个练习题&#xff1a; 再来一个练习&#xff1a; 这里我问了一下ChatGPT&#xff0c;如果一个值两侧分别趋近于正无穷&#xff0c;以及负无穷。理论上这个极限值应该说是不存…

虹科技术前沿 | TSN网络中时间感知整形器的性能验证实测

来源&#xff1a;虹科技术前沿 | TSN网络中时间感知整形器的性能验证实测 原文链接&#xff1a;https://mp.weixin.qq.com/s/h3hTRAAEVN42DjDRifGxnA 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; #时间敏感网络 #TSN #时间感知整形器 导读 本文旨在验证时间敏感…

vscode搭建rust开发环境

由于rustrover不是免费的&#xff0c;此处教学搭建一套基于vscode的rust开发环境&#xff0c;可运行&#xff0c;可调式 1.下载vscode1.91.1 Download Visual Studio Code - Mac, Linux, Windows 2.下载插件 打开网站下载插件 rust-analyzer-0.4.2049、vscode-lldb-1.10.0、…

SQL数据库如何修改表中栏位的长度

1.问题 已经建立的表中MEMO 栏位原来长度是20&#xff0c;随着使用需要将MEMO长度调整为200&#xff1b; 即 MEMO VARCHAR&#xff08;20&#xff09; → MEMO VARCHAR(200&#xff09; 2.修改办法 -- ALTER TABLE 表名 ALTER COLUMN 栏位名字 类型(长度);ALTER T…