访问构造方法(反射)

news2024/9/20 0:27:39

文章目录

  • 前言
  • 一、反射是什么?
  • 二、访问构造方法
    • 1.Constructor对象的获取方法
    • 2.Constructor方法的使用
  • 总结

前言

        Java的反射机制可以实现访问、检测和修改Java对象本身信息的功能,在java.lang.reflect包下提供此功能。可以使程序员更加深入地控制程序的运行过程。可以理解为随时调用某个类的某个构造方法,成员方法,属性。


一、反射是什么?

        Java反射是指在运行时(Runtime)动态获取和操作一个类的信息的能力。通过Java反射,可以在运行时获取类的属性、方法、构造函数等信息,并且可以动态调用这些属性和方法。

        Java反射允许程序在运行时动态加载、探知和使用编译时未知的类,对象,方法等,可以实现动态生成对象,动态调用方法,动态修改属性等功能。使用Java反射,可以实现一些框架和库的功能,例如Spring框架中的依赖注入、Hibernate框架中的ORM映射等。 

二、访问构造方法 

        Constructor类就是java反射机制的java.lang包下的具体方法。 

        使用Constructor对象可以访问相应的构造方法。获取Constructor对象需要使用以下的方法,返回Constructor类型的对象或数组。

1.Constructor对象的获取方法

获取构造方法的方法
方法功能描述
getConstructors()获取所有公有的构造方法
getConstructor(Class<?>...parameterTypes)获取对应的公有的构造方法
getDeclaredConstructors()获取所有的构造方法
getDeclaredConstructor(Class<?>...parameterTypes)获取指定的构造方法(无论是否私有)

        获取所有的构造方法,具体的一个例子,想要使用Constructor对象随时调用某类的构造方法,先实例化一个该类的对象,然后使用getClass()方法将该对象包装为原始类型Class,最后使用以上的方法获取所有的构造方法。

        实操展示:

Example example = new Example();
Class<? extends Example> exampleClass =example.getClass();            
Constructor constructor[] = exampleClass.getDeclaredConstructors();
//该constructor数组获取了example类的全部构造方法

         获取指定的构造方法,操作与以上步骤一致,唯一不同点在getDeclaredConstructor()的括号中填入 数据类型.Class 

        实操展示:

Example example = new Example();
Class<? extends Example> exampleClass =example.getClass();            
Constructor constructor = 
exampleClass.getDeclaredConstructor(String.class,int.class,int.class);
//该constructor对象操纵的构造方法数据类型为 String,int,int

        或者为:

Example example = new Example();
Class<? extends Example> exampleClass =example.getClass();            
Constructor constructor = 
exampleClass.getDeclaredConstructor(new Class{}[String.class,int.class,int.class]);
//该constructor对象操纵的构造方法数据类型为 String,int,int

2.Constructor方法的使用

Constructor类的常用方法
方法功能描述
isVarArgs()查看该构造方法是否允许带有可变数量的参数,如果允许返回ture,否则返回false
getParameterTypes()按照声明顺序以Class数组的形式获取该构造方法的各个参数的类型
getExceptionTypes()以Class数组的形式获取该构造方法可能抛出的异常
newInstance(Object...initarges)通过该构造方法利用指定参数创建一个该类的对象,如果未设置参数则表示采用默认无参数的构造方法
setAccessible(boolean flag)如果该构造方法的权限为private,flag值为ture的话,可以无视该权限
getModifiers()获取可以解析出该构造方法所采用修饰符的整数(private=0,protected=1,public=2)

        实操展示:

        原想调用的方法:

public class Example {
    String name=null;
    int age=0;
    int id=0;

    public Example(){}

    @SuppressWarnings("unused")
    private Example(int id){
        this.id=id;
    }

    public Example(String name,int age,int id){
        this.name=name;
        this.age=age;
        this.id=id;
    }

    
    public Example(String...strings){
        if(strings.length>0){
            this.name=strings[0];
        }
        if(strings.length>1){
            this.age=Integer.valueOf(strings[1]);
        }
        if(strings.length>2){
            this.id=Integer.valueOf(strings[2]);
        }
    }

    public void input(){
        System.out.println("姓名:"+name+" 年龄:"+age+" id="+id);
    }
}

        该Example类有四个构造方法,将在下面的Demo类中,使用Constructor类的常用方法,逐一调用,并输出各个构造方法的信息。

import java.lang.reflect.Constructor;

public class Demo{
    public static void main(String[] args) {
        Example person = new Example("张三", 18,101);
        Class<? extends Example> personC =person.getClass();
        @SuppressWarnings("rawtypes")
        Constructor[] declaredConstructors = personC.getDeclaredConstructors();
        for(int i=0;i<declaredConstructors.length;i++){
            Constructor<?> constructor = declaredConstructors[i];
            
            System.out.println("该类的名称:"+constructor.getName());
            //获取该构造方法的名称
            
            System.out.println("查看是否允许带有可变数量的参数:"+constructor.isVarArgs());
            //获取该构造方法的参数是否为可变的

            System.out.println("该构造方法的参数类型依次为:");
            @SuppressWarnings("rawtypes")
            Class type[]=constructor.getParameterTypes();
            if(type.length==0){
                System.out.println("该构造方法是无参的");
            }
            for(int j=0;j<type.length;j++){
                System.out.println(type[j]);
            }
            //获取该构造方法的参数类型

            System.out.println("该构造方法可能抛出的异常类型:");
            @SuppressWarnings("rawtypes")
            Class excpetion[]= constructor.getExceptionTypes();
            if(excpetion.length==0){
                System.out.println("无");
            }
            for(int j=0;j<excpetion.length;j++){
                System.out.println(excpetion[j]);
            }
            //获取该构造方法可能抛出的异常类型

             Example example =null;
             while (example==null) {
                try {
                    if (i==0) {
                        Object contect[] = new Object[]{new String[]{"王五","30","104"}};
                        example=(Example)constructor.newInstance(contect);  //此方法所填值为object对象,newInstance方法不接受原始类型,例如String,需要封装成Object类
                    }else if(i==1){
                        example=(Example)constructor.newInstance("李四",20,102);
                    }else if(i==2){
                        example=(Example)constructor.newInstance(103);
                    }else if (i==3) {
                        example=(Example)constructor.newInstance();
                    }   
                    //实例化各个构造方法
                } catch (ClassCastException e) {
                    e.printStackTrace();
                } catch (Exception e){
                    //如果创建对象时异常,方法为私有,运行以下方法
                    constructor.setAccessible(true);
                    e.printStackTrace();
                }
            } 
            if (example!=null) {
                example.input();
            }
            System.out.println("-------------------------------------");
        }
    }
}

        运行结果: 

        如上图当我们创建好一个该类的对象后,再转换为Constructor对象,就可以随时使用调用其newInstance()方法调用该类的构造方法,在代码运行的过程中实现动态调整数值。 

        补充:

Modifier类中的常用解析方法
静态方法功能描述
isPublic(int mod)查看是否被public修饰符修饰,如果是则返回true,否则返回false
isProtected(int mod)查看是否被protected修饰符修饰,如果是则返回true,否则返回false
isPrivate(int mod)查看是否被private修饰符修饰,如果是则返回true,否则返回false
isStatic(int mod)查看是否被static修饰符修饰,如果是则返回true,否则返回false
isFinal(int mod)查看是否被final修饰符修饰,如果是则返回true,否则返回false
toString(int mod)以字符串的形式返回所有修饰符

        举个例子说明如何使用。例子:判断contructor对象所代表的构造方法是否被final修饰符修饰,以及以字符串的形式获得该构造方法的所有修饰符的常写代码如下:

int modifiers = constructor.getModifiers();
//获取该constructor对象的构造方法的限制符整数值
boolean isEmbellishByPrivate = Modifier.isFinal(modifiers);
//是否被final修饰符修饰
String embellishment = Modifier.toString(modifiers);
//以字符串的形式获得该构造方法

总结

        以上就是今天要讲的内容,本文仅仅简单介绍了访问构造方法的使用,而反射提供了大量能使我们快速便捷地处理数据的函数和方法,指正的内容欢迎在评论区中留言。

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

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

相关文章

初识C语言——第二十九天

数组 本章重点 1.一维数组的创建和初始化 数组的创建 注意事项&#xff1a; 1.一维由低数组在内存中是连续存放的&#xff01; 2.随着数组下标的增长&#xff0c;地址是由低到高变化的 2.二维数组的创建和初始化 注意事项&#xff1a; 1.二维数组在内存中也是连续存放的&am…

内网横向移动小补充 --->PTK

大家别急&#xff0c;我的基于资源的约束性委派攻击还在写&#xff0c;这个东西一时半会讲不清楚&#xff0c;所以我在这里先来补充一点横向移动以前没说好的东西&#xff01;&#xff01;&#xff01; 在更啦&#xff0c;别催啦~~~~ 还记得我之前在内网渗透里面讲过这个PTK&a…

2024爆款神器!会声会影2024旗舰版,让你的视频制作技能暴涨,不学真的亏大了!

在数字内容创作的时代&#xff0c;视频编辑已经成为连接创意与现实的重要桥梁。无论是个人Vlog制作、在线教育课程、企业宣传还是专业影视制作&#xff0c;高效而强大的视频编辑软件成为了必不可少的工具。会声会影2024旗舰版&#xff0c;作为一款集先进技术与用户友好界面设计…

数据集007:垃圾分类数据集(含数据集下载链接)

数据集简介 本数据拥有 训练集&#xff1a;43685张&#xff1b; 验证集&#xff1a;5363张&#xff1b; 测试集&#xff1a;5363张&#xff1b; 总类别数&#xff1a;158类。 部分代码&#xff1a; 定义数据集 class MyDataset(Dataset):def __init__(self, modetrain, …

【MATLAB】去除趋势项(解决频谱图大部分为零的问题)

1.概 述 在许多实际信号分析处理中信号经FFT变换后得到的频谱谱线值几乎都为0&#xff0c;介绍这是如何形成的&#xff0c;又该如何去解决。 2.案例分析 读入一组实验数据文件(文件名为qldata.mat)&#xff0c;作出该组数据的频谱图。程序清单如下: clear; clc; close all;…

(四)手把手教你内网穿透,实现外网主机访问内网服务器

背景&#xff1a;书接上回&#xff0c; 服务器的使用-CSDN博客 课题组成员都有自己的账号&#xff0c;且能通过内网访问服务器&#xff0c;进行远程连接了。我们知道内网中的主机可以访问公网的主机&#xff0c;反之不可以访问。那么如果课题组成员在家不在内网区域内&#x…

重生之 SpringBoot3 入门保姆级学习(07、整合 Redis 案例)

重生之 SpringBoot3 入门保姆级学习&#xff08;07、整合 Redis 案例&#xff09; 导入 Maven 依赖并刷新 Maven <dependencies><!--springboot3 Web 依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring…

nginx流量监控:goAccess安装与使用

关于goAccess GoAccess 是一款实时、快速的日志分析工具&#xff0c;专门设计用于分析Web服务器日志&#xff0c;特别是Nginx日志。 安装 &#xff08;1&#xff09;准备相关依赖 # Missing development libraries for ncursesw # centOS yum install -y ncurses-devel # U…

动态规划-似包非包问题

组合总和 Ⅳ&#xff08;377&#xff09; 题目描述&#xff1a; 状态表示&#xff1a; 我们看到这题发现有一个限制条件就是目标整数target并且此时数组中的数字是可以重复选择的&#xff0c;这时候不难联想到前面学习的完全背包问题&#xff0c;这题好像符合完全背包问题的…

【开源】加油站管理系统 JAVA+Vue.js+SpringBoot+MySQL

目录 一、项目介绍 论坛模块 加油站模块 汽油模块 二、项目截图 三、核心代码 一、项目介绍 Vue.jsSpringBoot前后端分离新手入门项目《加油站管理系统》&#xff0c;包括论坛模块、加油站模块、汽油模块、加油模块和部门角色菜单模块&#xff0c;项目编号T003。 【开源…

nuxt2:自定义指令 / v-xxx / directives / 理解 / 使用方法 / DEMO

一、理解自定义指令 在 vue 中提供了一些对于页面和数据更为方便的输出&#xff0c;这些操作就叫做指令&#xff0c;以 v-xxx 表示&#xff0c;比如 html 页面中的属性 <div v-xxx ></div>。自定义指令很大程度提高了开发效率&#xff0c;提高了工程化水平&#x…

【读书】读书笔记——理科生的视角:底层逻辑+数学之美

1&#xff0c;底层逻辑1&#xff08;看清这个世界的底牌&#xff09; 刘润 著 0&#xff09;什么是底层逻辑&#xff1f; 底层逻辑是&#xff1a;事物之间共同点、变化背后不变的东西事&#xff1b;看清事物的本质&#xff0c;才能在复杂变化中从根本上解决问题。 1&#x…

基于51单片机的智能灯光控制系统

一.硬件方案 智能灯光控制系统由单片机最小系统、人体感应模块、关照强度模块、灯光控制模块、电源模块和灯泡组成。本文以STC89C52单片机为核心&#xff0c;通过利用光照度和红外人体感应相结合主动与被动的探测方法&#xff0c;现了室内无人或者关照充足时灯光自动光灯&…

PyCharm面板ctrl+鼠标滚轮放大缩小代码

1.【File】➡【Settings】 2.点击【Keymap】&#xff0c;在右边搜索框中搜incre&#xff0c;双击出现的【Increase Font Size】 3.在弹出的提示框中选择【Add Mouse Shortcut】 4.弹出下面的提示框后&#xff0c;键盘按住【ctrl】&#xff0c;并且上滑鼠标滚轮。然后点击【O…

第十七讲:结构体

第十七讲&#xff1a;结构体 1.初始结构体1.1结构体声明1.2结构体变量的创建和初始化1.2.1结构体变量的创建1.2.2结构体变量的初始化1.2.2.1普通初始化1.2.2.2结构体数组1.2.2.3结构体指针 1.3typedef定义结构体1.4结构体的自引用1.5结构体的特殊声明 2.结构体内存对齐2.1对齐规…

【C++初阶】—— 类和对象 (上)

&#x1f4dd;个人主页&#x1f339;&#xff1a;EterNity_TiMe_ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 类和对象 1. 初步认识C2. 类的引入3. 类的定义声明和定义全部放在类体中声明和定义分开存放 4.…

用队列实现栈 用栈实现队列 设计循环队列

用队列实现栈 思路 栈的特点&#xff1a;后进先出 队列的特点&#xff1a;先进先出 使用两个队列实现栈&#xff1a; 我们可以使用两个队列&#xff0c;一个队列为&#xff1a;空队列&#xff0c;一个队列为&#xff1a;非空队列 当我们要出队列时&#xff1a; 将 size - …

束测后台实操文档1-PVE、PBS

合肥先进光源束测系统后台基础架构初步设计报告 合肥先进光源束测系统后台搭建进展2024.4.29 关于后台基础架构&#xff0c;写了上面两篇文档&#xff0c;只是框架的印象&#xff0c;没涉及到具体的实操&#xff0c;后面针对具体的搭建慢慢的完善操作的细节&#xff0c;从今年…

灌装线在线粒子浮游菌监测系统安装调试

近日&#xff0c;北京中邦兴业成功完成了某企业灌装线多个点位的洁净环境在线粒子浮游菌监测系统的施工并完成了前期的调试工作。 【项目现场】 北京中邦兴业技术工程师根据客户现场实际情况&#xff0c;进行了粒子、浮游菌的点位布置&#xff0c;此系统能够实时监测生产线上的…

Docker安装MySQL的详细教程

1. 拉取MySQL镜像 拉取MySQL镜像。您可以指定版本号&#xff0c;例如5.7或8.0&#xff0c;如果不指定&#xff0c;默认会拉取最新稳定版。 docker pull mysql:5.7或者&#xff0c;使用最新版本&#xff1a; docker pull mysql:latest2. 运行MySQL容器 拉取镜像完成后&#…