【第十五章 java反射机制,获取Class类的实例,创建运行时类的对象,调用运行时类中指定的结构】

news2025/1/13 15:43:50

第十五章 java反射机制,获取Class类的实例,创建运行时类的对象,调用运行时类中指定的结构

1.java反射机制概述
加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,我们形象的称之为:反射
在这里插入图片描述

 @Test
    public void test() throws Exception {
        Class clazz= Person.class;
        //1.通过反射,创建Person类的对象
        Constructor cons=clazz.getConstructor(String.class,int.class);
        Object obj=cons.newInstance("Tom",12);
        Person p=(Person)obj;
        System.out.println(p.toString());
        //2.通过反射,调用对象指定的属性和方法
        Field age = clazz.getDeclaredField("age");
        age.set(p,10);
        System.out.println(p.toString());
        Method show = clazz.getDeclaredMethod("show");
        show.invoke(p);
        System.out.println("***************************");
    }

2.关于java.lang.Class类的理解
(1)类的加载过程:程序在经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾),接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件加载到内存中,此过程就称为类的加载。加载到内存中的类称为运行时类,此运行时类,就作为Class的一个实例。
(2)换句话说,Class的实例就对应着一个运行时类。
(3)加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式来获取此运行时类。
3.获取Class类的实例

//获取Class类的实例
    @Test
    public void test1() throws ClassNotFoundException {
        //方式一:调用运行时类的属性:class
        Class clazz1=Person.class;
        System.out.println(clazz1);
        //方式二:通过运行时类的对象,调用getClass()
        Person p1=new Person();
        Class clazz2=p1.getClass();
        System.out.println(clazz2);
        //方式三:调用Class的静态方法:forName(String classpath)
        Class clazz3 = Class.forName("day15.Person");
        System.out.println(clazz3);
        //使用类的加载器(了解)
        ClassLoader classLoader = ReflectionTest.class.getClassLoader();
        Class clazz4=classLoader.loadClass("day15.Person");
        System.out.println(clazz4);
    }

4.创建运行时类的对象
通过反射创建对应的运行时类的对象

 @Test
    public void test() throws IllegalAccessException, InstantiationException {
        Class<Person> clazz=Person.class;
        /**
         * newInstance():调用此方法,创建运行时类的对象,内部调用了运行时类的空参构造器
         * 要想此方法正常的创建运行时类的对象,要求:
         * 1.运行时类必须提供空参的构造器
         * 2.空参的构造器的访问权限得够,通常设置为public
         * 在javabean中要求提供一个public的空参构造器。原因:
         * 1.便于通过反射,创建运行时类的对象
         * 2.便于子类继承此运行时类时,默认调用super()时,保证父类哟此构造器
         */
        Person obj = clazz.newInstance();//调用Person类的空参构造器
        System.out.println(obj);
    }

(1)获取当前运行时类的属性结构:

public class FieldTest {
    @Test
    public void test(){
        Class clazz=Person.class;
        //获取属性结构
        //getFields():获取当前运行时类及其父类中声明为public访问权限的属性
        Field[] fields = clazz.getFields();
        for(Field field:fields){
            System.out.println(field);
        }
        System.out.println("**************************");
        //getDeclaredFields():获取当前运行时类中声明的所有属性。(不包含父类中声明的属性)
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field f:declaredFields){
            System.out.println(f);
        }
    }
    //权限修饰符 数据类型 变量名
    @Test
    public void test1(){
        Class clazz=Person.class;
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field f:declaredFields){
            //1.权限修饰符
            int modifiers = f.getModifiers();
            System.out.print(Modifier.toString(modifiers)+"\t");
            //2.数据类型
            Class type = f.getType();
            System.out.print(type.getName()+"\t");
            //3.变量名
            String name = f.getName();
            System.out.print(name);
            System.out.println();
        }
    }
}

(2)获取运行时类的方法结构:

public class MethodTest {
    @Test
    public void test(){
        Class clazz=Person.class;
        //getMethods():获取当前运行时类及其所有父类中声明为public权限的方法
        Method[] methods = clazz.getMethods();
        for(Method m:methods){
            System.out.println(m);
        }
        System.out.println();
        //getDeclaredMethods():获取当前运行时类中声明的所欲方法(不包含父类中声明的方法)
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for(Method m:declaredMethods){
            System.out.println(m);
        }
    }
    /**
     * @Xxxx
     * 权限修饰符 返回值类型 方法名(参数类型1 形参名1,...)throws XxxException{}
     */
    @Test
    public void test1(){
        Class clazz=Person.class;
        Method[] methods = clazz.getMethods();
        for(Method m:methods){
            //1.获取方法声明的注解
            Annotation[] annotations = m.getAnnotations();
            for(Annotation a:annotations){
                System.out.println(a);
            }
            //2.权限修饰符
            int modifiers = m.getModifiers();
            System.out.print(Modifier.toString(modifiers)+"\t");
            //3.返回值类型
            System.out.print(m.getReturnType().getName()+"\t");
            //4.方法名
            System.out.print(m.getName());
            System.out.print("(");
            //5.形参列表
            Class[] parameterTypes = m.getParameterTypes();
            if(!(parameterTypes==null&&parameterTypes.length==0)){
                for(int i=0;i<parameterTypes.length;i++){
                    if(i==parameterTypes.length-1){
                        System.out.print(parameterTypes[i].getName()+"args_"+i);
                        break;
                    }
                    System.out.print(parameterTypes[i].getName()+"args_"+i+",");
                }
            }
            System.out.print(")");
            System.out.println();
            //6.抛出的异常
            Class[] exceptionTypes = m.getExceptionTypes();
            if(!(exceptionTypes==null&&exceptionTypes.length==0)){
                System.out.print("throws");
                for(int i=0;i<exceptionTypes.length;i++){
                    if(i==exceptionTypes.length-1){
                        System.out.print(exceptionTypes[i].getName());
                        break;
                    }
                    System.out.print(exceptionTypes[i].getName()+",");
                }
            }
            System.out.println();
        }
    }
}

(3)获取构造器结构:

  @Test
    public void test(){
        Class clazz=Person.class;
        //getConstructors():获取当前运行时类中声明为public的构造器
        Constructor[] constructors = clazz.getConstructors();
        for(Constructor c:constructors){
            System.out.println(c);
        }
        System.out.println();
        //获取当前运行时类中声明的所有的构造器
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        for(Constructor c:declaredConstructors){
            System.out.println(c);
        }
    }

5.调用运行时类中指定的结构
(1)如何操作运行时类中的指定的属性:

 @Test
    public void testField1() throws Exception {
        Class clazz=Person.class;
        //创建运行时类的对象
        Person p=(Person)clazz.newInstance();
        //1.getDeclaredField(String name):获取运行时类中指定变量名的属性
        Field name= clazz.getDeclaredField("name");
        //2.保证当前属性是可访问的
        name.setAccessible(true);
        //3.获取、设置指定对象的属性值
        name.set(p,"tom");
        System.out.println(name.get(p));
    }

(2)如何操作运行时类中的指定的方法:

@Test
    public void testMeThod() throws Exception {
        Class clazz=Person.class;
        //创建运行时类的对象
        Person p=(Person)clazz.newInstance();
        //1.获取指定的某个方法
        //getDeclaredMethod():参数1:指明获取的方法的名称   参数2:指明获取的方法的形参列表
        Method show = clazz.getDeclaredMethod("show", String.class);
        //2.保证当前方法是可访问的
        show.setAccessible(true);
        //3.invoke():参数1:方法的调用者  参数2:给方法形参赋值的实参
        //invoke()的返回值即为对应类中调用的方法的返回值
        Object chn = show.invoke(p, "CHN");
        System.out.println(chn);
    }

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

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

相关文章

[计算机毕业设计]改进粒子群算法的监测资源调度

前言 &#x1f4c5;大四是整个大学期间最忙碌的时光,一边要忙着准备考研,考公,考教资或者实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过…

【学海】中位数(Median)的介绍以及如何在不同条件下计算中位数

一、什么是中位数 中位数是指将数据按大小顺序排列起来&#xff0c;形成一个数列&#xff0c;居于数列中间位置的那个数据。中位数用Me表示。 从中位数的定义可知&#xff0c;所研究的数据中有一半小于中位数&#xff0c;一半大于中位数。中位数的作用与算术平均数相近&#…

CAD DWG 比较--DWG Compare ActiveX Control

DWG Compare ActiveX Control AutoDWG DWG 比较 ActiveX 控件&#xff0c;比以往更快&#xff01; DWGCompareX 是一个主动控件 (COM)&#xff0c;可帮助您找出 AutoCAD 图形版本之间的差异并以图形方式显示它们。 主要特征&#xff1a; 显示视图中的差异&#xff0c;对添加的实…

LeetCode-剑指51-数组中的逆序对

1、归并排序 我们可以利用归并排序在合并两个数组时会比较两个数组中的值来确定有多少逆序对。我们用左指针指向左边的数组&#xff0c;右指针指向右边的数组。每当左指针右移时&#xff0c;我们在总数上加上右指针指向位置与起始位置的差值即可。 class Solution { public:i…

基于stm32单片机自动灭火火灾报警装置Proteus仿真

资料编号&#xff1a;102 下面是相关功能视频演示&#xff1a; 102-基于stm32单片机自动灭火火灾报警装置Proteus仿真&#xff08;仿真源码全套资料&#xff09;功能介绍&#xff1a; 火焰传感器的原理&#xff1a;是通过感知外部特殊波段光照强度的突变来判断是否出现火灾&a…

[附源码]java毕业设计汽车租赁管理系统论文

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

C++11 原子变量

目录 什么时原子变量&#xff1f; atomic 类成员 原子变量的使用 C/CLinux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂 什么时原子变量&#xff1f; 原子操作 原子指的是一系列不被 CPU上下文交换的机器指令&#xff0c;这些指令组合在一起就形成了原子操作。…

Design A Twitter Search

title: Notes of System Design No.08 — Design a Twitter Search description: ‘Design a Twitter Search’ date: 2022-05-13 18:01:58 tags: 系统设计 categories: 系统设计 00. What is Twitter Search? 01.Functional Requirement 02. Non-Functional Requirement 03…

【JavaSE】阶段性小结,运用Java实现图书管理系统

文章目录逻辑分析主题框架具体方法添加书籍删除书籍查找书籍借阅书籍归还书籍展示书籍退出系统源码UserNormalUserAdmintUserBookBookListIOperationAddboookOperationDeletbookOperationFindbookOperationShowbookOperationBorrowbookOperationReturnbookOperationExitOperati…

[计算机毕业设计]关联挖掘的服装推荐系统

前言 &#x1f4c5;大四是整个大学期间最忙碌的时光,一边要忙着准备考研,考公,考教资或者实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过…

OS>>多线程

文章目录绪论SIGCHLDvolatile概念执行流并行与并发临界资源与临界区互斥和同步线程线程定义线程独立性线程优点线程缺点线程ID线程操作线程创建线程等待线程终止线程分离线程替换线程互斥与同步互斥同步原子性互斥锁/互斥量原理使用抢票情景模拟未加锁前加锁后代码锁使用规范重…

【毕业设计】14-基于单片机的健康检测仪/心跳/温度/血压设计(原理图+源码+仿真工程+论文)

【毕业设计】14-基于单片机的健康检测仪/心跳/温度/血压设计&#xff08;原理图源码仿真工程论文&#xff09; 文章目录【毕业设计】14-基于单片机的健康检测仪/心跳/温度/血压设计&#xff08;原理图源码仿真工程论文&#xff09;资料下载链接任务书设计说明书摘要设计框架架构…

Android BLE HIDS Data ,从问询DB 到写入Android 节点的flow 之五

问题点 7&#xff1a; 关于BLE HIDS data 写入到Android 节点"/dev/uhid"的flow&#xff1b; 关于BLE中的HIDS&#xff0c;首先我们需要理解好角色的定义&#xff1a; GATT Server 作为HID Service 提供者&#xff0c;对应HID Device角色&#xff1b; GATT Client…

maven大全(概述、安装配置、使用步骤)

一、概述 1.什么是maven&#xff1f; 答&#xff1a; 全称是Apache Maven。专门用于管理和构建项目的工具 2.maven有什么作用&#xff1f; &#xff08;1&#xff09;提供了一套标准化的项目结构 官方&#xff1a; 就是使用的idea&#xff0c;eclipse编译器的项目结构不统…

基于Matlab的高压直流输电系统仿真研究

目录 摘要 I Abstract II 第1章 绪论 1 1.1 高压直流输电系统 1 1.2 高压直流输电系统的历史 1 1.3 高压直流输电系统的特点 1 1.4 我国高压直流输电系统的现状 2 1.5 高压直流输电技术的发展前景 5 第2章 高压直流输电控制基本原理 6 2.1 高压直流输电控制系统分层结构 6 2.2 …

领夹直播麦克风常规的使用方法及方案说明

麦克风多对我们来说并不陌生&#xff0c;但领夹式麦克风我们日常可能会用的比较少&#xff0c;像做自媒体、采访等会用到的比较多&#xff0c;它能收到人说话的声音&#xff0c;避开外界嘈杂的声音。接下来我们一起来了解一下领夹式麦克风的相关知识吧&#xff01; 一、领夹式麦…

Win11系统启动文件夹是空的怎么解决?

Win11系统启动文件夹是空的怎么解决&#xff1f;有用户发现自己系统的启动文件夹里面没有任何的文件&#xff0c;这样可能会导致我们的电脑出现问题&#xff0c;导致无法正常的启动桌面程序。那么如何去解决这个问题&#xff0c;一起看看具体的解决方法分享吧。 解决方法&#…

从I/O的视角看DPU

计算的流动性 随手翻开一个公有云&#xff0c;都会发现有不同的计算实例&#xff0c;搭配不同的CPU、内存、网络和存储来应对不同业务的需求. 当云原生和大量的新技术出现后&#xff0c;作为公有云考虑的最重要的一件事情就是提供这些丰富服务的成本: 青云、Ucloud也都在A股上…

[Redis] Spring Boot 使用Redis---RedisTemplate泛型约束乱码问题

✨✨个人主页:沫洺的主页 &#x1f4da;&#x1f4da;系列专栏: &#x1f4d6; JavaWeb专栏&#x1f4d6; JavaSE专栏 &#x1f4d6; Java基础专栏&#x1f4d6;vue3专栏 &#x1f4d6;MyBatis专栏&#x1f4d6;Spring专栏&#x1f4d6;SpringMVC专栏&#x1f4d6;SpringBoot专…

牛客网-《刷C语言百题》第五期

✅作者简介&#xff1a;嵌入式入坑者&#xff0c;与大家一起加油&#xff0c;希望文章能够帮助各位&#xff01;&#xff01;&#xff01;&#xff01; &#x1f4c3;个人主页&#xff1a;rivencode的个人主页 &#x1f525;系列专栏&#xff1a;《C语言入门必刷百题》 &#x…