反射-认识反射

news2024/10/6 18:28:55

一、什么是反射

二、如何使用反射

1.第一步:加载类,获取类的字节码(获取类的Class对象)

public class reflectTest {
    public static void main(String[] args) throws Exception {
     Class c1 =  Student.class; //通过类名得到学生类的Class对象
        System.out.println ( c1.getName () );//全类名  study.reflect.Student
        System.out.println ( c1.getSimpleName () );//简名: Student

        Class c2 = Class.forName ( "study.reflect.Student" );//必须填入类的全类名
        System.out.println (c1==c2);//true   拿到的是同一个对象
        Student s= new Student ();
        Class  c3 = s.getClass ();
        System.out.println (c2==c3);//true

    }
}

2.获取类的构造器

import org.junit.Test;

import java.lang.reflect.Constructor;

public class Test2Constructor {
    @Test
    public void test1(){
   //1.反射第一步必须先得到这个类的Class对象
   Class c1=Cat.class;
   //2.获取类的全部构造器
//        Constructor[] constructors = c1.getConstructors ();//只能拿public修饰的构造器
        Constructor[] constructors = c1.getDeclaredConstructors ();//获取所有声明的构造器,不管是什么修饰符的
   //3.遍历数组中的每个构造器对象
        for (Constructor constructor : constructors) {
            System.out.println (constructor.getName ()+"--->"+constructor.getParameterCount ());//获得构造器的参数数量

        }
    }
    @Test
    public void testGetConstructor() throws Exception {
        //1.反射第一步必须先得到这个类的Class对象
        Class c=Cat.class;
        //2.获取某个构造器:无参构造器
        Constructor constructor = c.getConstructor ();//只能拿public修饰的构造器  须填入参数类型
        Constructor declaredConstructor = c.getDeclaredConstructor ();//可以拿到所有权限修饰的构造器
        System.out.println (constructor.getName ()+"--->"+constructor.getParameterCount ());
        System.out.println (declaredConstructor.getName ()+"--->"+declaredConstructor.getParameterCount ());
        //3.获取有参数的构造器
        Constructor constructor1 = c.getConstructor ( String.class, int.class );
        Constructor constructor2 = c.getDeclaredConstructor ( String.class, int.class );
        System.out.println (constructor1.getName ()+"--->"+constructor1.getParameterCount ());
        System.out.println (constructor2.getName ()+"--->"+constructor2.getParameterCount ());

    }
}

3.用构造器可以通过反射初始化对象

import org.junit.Test;

import java.lang.reflect.Constructor;

public class Test2Constructor {
    @Test
    public void test1(){
   //1.反射第一步必须先得到这个类的Class对象
   Class c1=Cat.class;
   //2.获取类的全部构造器
//        Constructor[] constructors = c1.getConstructors ();//只能拿public修饰的构造器
        Constructor[] constructors = c1.getDeclaredConstructors ();//获取所有声明的构造器,不管是什么修饰符的
   //3.遍历数组中的每个构造器对象
        for (Constructor constructor : constructors) {
            System.out.println (constructor.getName ()+"--->"+constructor.getParameterCount ());//获得构造器的参数数量

        }
    }
    @Test
    public void testGetConstructor() throws Exception {
        //1.反射第一步必须先得到这个类的Class对象
        Class c=Cat.class;
        //2.获取某个构造器:无参构造器
//        Constructor constructor = c.getConstructor ();//只能拿public修饰的构造器  须填入参数类型
        Constructor declaredConstructor = c.getDeclaredConstructor ();//可以拿到所有权限修饰的构造器
//        System.out.println (constructor.getName ()+"--->"+constructor.getParameterCount ());
        System.out.println (declaredConstructor.getName ()+"--->"+declaredConstructor.getParameterCount ());
        //3.获取有参数的构造器
//        Constructor constructor1 = c.getConstructor ( String.class, int.class );
        Constructor constructor2 = c.getDeclaredConstructor ( String.class, int.class );
//        System.out.println (constructor1.getName ()+"--->"+constructor1.getParameterCount ());
        System.out.println (constructor2.getName ()+"--->"+constructor2.getParameterCount ());
        declaredConstructor.setAccessible ( true );//禁止检查访问权限
        Cat cat = (Cat) declaredConstructor.newInstance ();
        System.out.println ( cat );
        constructor2.setAccessible ( true );
        Cat cat1 = (Cat) constructor2.newInstance ( "咪咪", 2 );
        System.out.println ( cat1 );

    }
}

4.获取类的成员变量

import org.junit.Test;

import java.lang.reflect.Field;

public class Test3Constructor {
    @Test
    public void testGetFields() throws Exception {
        //1.反射第一步,必须先拿到类的Class对象
        Class c1=Cat.class;
        //2.获取类的全部成员变量
        Field[] fields = c1.getDeclaredFields ();
        //3.遍历数组
        for (Field field : fields) {
            System.out.println ( field.getName ()+"---->"+field.getType () );
        }
        //4.定位某个成员变量
        Field fname = c1.getDeclaredField ( "name" );
        System.out.println (fname.getName ()+"--->"+ fname.getType () );
        //5.复制
        Cat cat=new Cat ();
        fname.setAccessible ( true );
        fname.set ( cat,"加菲猫" );
        System.out.println ( cat );
        //6.取值
        String name = (String) fname.get ( cat );
        System.out.println ( name );
    }
}

5.获取类的成员方法,并执行方法

import org.junit.Test;

import java.lang.reflect.Method;

public class TestMethod {
    @Test
    public void getMehtod() throws Exception {
        //1.反射第一步:先得到class对象
        Class c=Cat.class;
        //2.获取类的全部成员方法
        Method[] methods = c.getMethods ();//只能获取public修饰的方法
        for (Method method : methods) {
            System.out.println ( method.getName ()+"---->"+method.getParameterCount ()+"---->"+method.getReturnType () );
        }
        System.out.println ("-----------------------------------------");
        Method[] declaredMethods = c.getDeclaredMethods ();//获取所有权限的方法
        for (Method declaredMethod : declaredMethods) {
            System.out.println ( declaredMethod.getName ()+"---->"
            +declaredMethod.getParameterCount ()+"---->"+declaredMethod.getReturnType ());//返回返回值类型
        }
        System.out.println ("-----------------------------------------");
        //3.获取某个方法对象
        Method run = c.getDeclaredMethod ( "run" );
        System.out.println (run.getName ()+"---->"+run.getParameterCount ()+"---->"+run.getReturnType ());//run---->0---->void
        Cat cat = new Cat ();
        run.setAccessible ( true );
        run.invoke (cat);//必须传入触发方法的对象

    }
}

三、反射的作用,应用场景

1.反射的作用

2.使用反射做一个简易版的框架

框架类

import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;

public class ObjectFrame {
    //保存任意对象的字段和其数据保存带文件中
    public static void saveObject(Object obj) throws Exception {
        PrintStream ps = new PrintStream (new FileOutputStream ( "\\xuexiaaa\\src\\666.txt" ,true),true );
        //obj 是任意对象,到底要有多少个字段要保存?
        Class c = obj.getClass ();
        String cName = c.getSimpleName ();
        ps.println ("--------------------"+c+"----------------------");
        //2.从这个类中提取它的全部成员变量
        Field[] fields = c.getDeclaredFields ();
        //3.遍历每个成员变量
        for (Field field : fields) {
            //4.拿到成员变量的名字
            field.setAccessible ( true );
            String name = field.getName ();
            //5.拿到这个成员变量在对象中的数据
            String value =  field.get ( obj )+"";
            ps.println (name+"="+value);

        }
        ps.close ();

    }
}

测试类

public class TestFrame {
    public static void main(String[] args) throws Exception {
        Student s1 = new Student ( "吴彦祖", 18, "男" );
        Teacher t1 = new Teacher ( "八八", 99.9 );
    //需求把任意对象的字段名和其对应的信息
        ObjectFrame.saveObject ( s1 );
        ObjectFrame.saveObject ( t1 );

    }
}

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

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

相关文章

上班后很迷茫,到底该如何做一个合格的测试?

【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程,刷完面试就稳了,你也可以当高薪软件测试工程师(自动化测试) 如何做一个合格的测试?软件测试工程师的岗位职责到底是什么? 最初,我…

倒计时列表实现(小程序端Vue)

//rich-text主要用来将展示html格式的&#xff0c;可以直接使用这个标签 <view class"ptBox" v-for"(item,index) in orderList" :key"index"> <rich-text :nodes"item.limit_time|limitTimeFilter"></rich-text>…

vue+three.js中使用Ammo.js

直接通过npm i ammo.js安装进webpack的项目里调用时&#xff0c;会出现如下报错&#xff1a; ERROR in ./node_modules/ammo.js/ammo.js 1:1683-1696 Mo…

VMware中安装Ubuntu(2023年)

Ubuntu安装 前言 安装过程中电脑发热时正常的&#xff0c;这个还是稍微有点点大&#xff1b;下载的版本根据自己的喜好来&#xff0c;新版本肯定要比旧版本占用的空间更大&#xff0c;大家自行选择&#xff1b;仅供学习使用的话可以下载成熟稳定的版本&#xff0c;例如16、18…

【新版】系统架构设计师 - 案例分析 - 架构设计<SOA与微服务>

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 案例分析 - 架构设计&#xff1c;SOA与微服务&#xff1e;例题1例题2例题3例题4 架构 - 案例分析 - 架构设计&#xff1c;SOA与微服务&#xff1e; 这里SOA与微服务的例题只对应找寻了几个&#x…

servlet开发-通过Tomcat部署一个简单的webapp

首先我们得下载安装Tomcat&#xff0c;推荐看Tomcat&#xff08;HTTP服务器&#xff09;下载以及认识&#xff0c; 我们将通过打印一个hello word的方式来熟悉servlet开发,通过Tomcat部署一个webapp的流程 servlet的含义 Tomcat提供了一系列的api接口&#xff0c;这些api背后…

dfs力扣1993树上的操作

文章目录 dfs力扣1993树上的操作题目示例提示做题历程做题思路数组定义编写代码 完整代码 dfs力扣1993树上的操作 题目 题目链接 给你一棵 n 个节点的树&#xff0c;编号从 0 到 n - 1 &#xff0c;以父节点数组 parent 的形式给出&#xff0c;其中 parent[i] 是第 i 个节点…

Java多线程篇(5)——cas和atomic原子类

文章目录 CASAtomic 原子类一般原子类针对aba问题 —— AtomicStampedReference针对大量自旋问题 —— LongAdder CAS 原理大致如下&#xff1a; 在java的 Unsafe 类里封装了一些 cas 的api。以 compareAndSetInt 为例&#xff0c;来看看其底层实现。 可以发现&#xff0c;最…

基于abaqus的非等速生长Voronoi晶体模型生成插件

1. 非等速生长晶体模型简介 对于标准Voronoi而言&#xff0c;每个晶粒的生长速率是相同的&#xff0c;任意两个晶粒的交界线为其形核点连线的垂直平分线&#xff0c;交界线为一条直线&#xff0c;如图1.1所示。 图1.1 标准Voronoi晶粒交界线 而对于非等速生长Voronoi晶体而言…

项目篇——java文档搜索引擎

Java 文档搜索引擎 文章目录 Java 文档搜索引擎一、分词二、完成parser 类2.1、排除非html文件2.2、解析html以下是解析 HTML 标题的方法以下是解析 对应的 URL以下是解析 HTML的正文&#xff1a; 补充&#xff1a;倒序索引 三、实现 index 类3.1、实现索引结构3.2、索引中新增…

学会使用Git 和 GitHub

Git 和 GitHub 都是程序员每天都要用到的东西 —— 前者是目前最先进的 版本控制工具&#xff0c;拥有最多的用户&#xff0c;且管理着地球上最庞大的代码仓库&#xff1b;而后者是全球最大 同性交友 代码托管平台、开源社区。 在没有这两个工具时&#xff0c;编程可能是这样的…

Go环境搭建

下载 官网地址 选择Download 根据自己的请选择对应的版本进行下载(我这里使用windos go.1.21.1版本) 我这里选择zip类型进行下载免安装版(你也可以选择mis类型进行下载,安装版一步一步next就行)。 安装 解压安装包 目录说明 配置环境变量 验证是否安装成功 完成上述配置…

通过插件去除Kotlin混淆去除 @Metadata标记

在Kotlin中&#xff0c;Metadata是指描述Kotlin类的元数据。它包含了关于类的属性、函数、注解和其他信息的描述。Metadata的作用主要有以下几个方面&#xff1a; 反射&#xff1a;Metadata可以用于在运行时获取类的信息&#xff0c;包括类的名称、属性、函数等。通过反射&…

【功能设计】数据分发功能设计

文章目录 设计脑图功能性非功能性 功能设计文档1. 需求分析1.1、功能性需求1.2、非功能性需求 2. 功能设计2.1 业务流程图2.2 数据流图2.3 表结构设计2.4 接口设计2.5 功能点 3.非功能性设计3.1 性能3.2 可用性3.3 并发性3.4 安全性 设计脑图 功能性 非功能性 功能设计文档 1…

国庆中秋特辑(三)使用生成对抗网络(GAN)生成具有节日氛围的画作,深度学习框架 TensorFlow 和 Keras 来实现

要用人工智能技术来庆祝国庆中秋&#xff0c;我们可以使用生成对抗网络&#xff08;GAN&#xff09;生成具有节日氛围的画作。这里将使用深度学习框架 TensorFlow 和 Keras 来实现。 一、生成对抗网络&#xff08;GAN&#xff09; 生成对抗网络&#xff08;GANs&#xff0c;…

FFMpeg zoompan 镜头聚焦和移动走位

案例 原始图片 # 输出帧数&#xff0c;默认25帧/秒&#xff0c;25*4 代表4秒 # s1280x80 # 输出视频比例&#xff0c;可以设置和输入图片大小一致 # zoom0.002 表示每帧放大的倍数&#xff0c;下面代码是25帧/每秒 * 4秒&#xff0c;共1000帧 # 最终是 0.002*25*4 0.2&…

什么是深度学习?最易懂的机器学习入门文章

1. 什么是深度学习? 深度学习是机器学习领域中一个新的研究方向&#xff0c;它被引入机器学习使其更接近于人工智能。 原文&#xff1a;【科普&实践】超详细&#xff01;一文带你玩转深度学习 - 飞桨AI Studio星河社区 深度学习是机器学习领域中一个新的研究方向&#xff…

折腾LINUX复古终端

这个复古终端是cool-retro-term&#xff0c;先来图 点击GITHUB地址 开始用docker运行&#xff0c;报错。后来用x11docker&#xff0c;因为我要远程通过SSH的x11转发&#xff0c;但实际x11docker的默认backbone就说docker&#xff0c;也就说要先用docker下载镜像&#xff0c…

[maven] 实现使用 plugin 及 properties 简述

[maven] 实现&使用 plugin 及 properties 简述 这章内容&#xff0c;我个人感觉可看可不看……&#xff1f; 不过课都上了&#xff0c;笔记 &#x1f4d2; 补完才对得起自己嘛 plugins 主要讲一下 maven 的 plugin 时怎么实现的&#xff0c;以及项目中怎么调用自己实现…

成集云 | 用友T+集成聚水潭ERP(用友T+主管供应链)| 解决方案

源系统成集云目标系统 方案介绍 用友T是一款由用友畅捷通推出的新型互联网企业管理系统&#xff0c;它主要满足成长型小微企业对其灵活业务流程的管控需求&#xff0c;并重点解决往来业务管理、订单跟踪、资金、库存等管理难题。 聚水潭是一款以SaaS ERP为核心&#xff0c;集…