反射、枚举

news2024/12/23 4:32:37
  1. 反射的定义:Java的反射机制是在运行状态中,都能对任意的类拿到这个类的所有属性,从而对其进行相应的修改;
  2. 用途:在日常第三方应用开发中,可以通过反射机制来获取某个类的私有成员变量或是方法;主要是用来开发各种通用框架;
  3. 优缺点:

        优

        1) 对于任意一个类,都能够知道这个类的所有属性和方法;

            对于任意一个对象,都能够调用它的任意一个方法;

        2) 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力

        3) 反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。

        缺        

        1) 使用反射会有效率问题。会导致程序效率降低。

            具体参考这里:http://www.imooc.com/article/293679

        2) 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 

4.反射相关的类:获取类的相关方法:

方法用途
getClassLoader()获得类的加载器
getDeclaredClasses()返回一个包含该类中所有类和接口类的对象数组
forName(String className)根据类名返回类对象
newInstance()创建类的实例
getName()获得类的完整路径名字

获取类中属性的相关的方法

方法用途
getField(String name)获得某个公有的属性对象
getFields()获得所有公有的属性对象
getDeclaredField(String name)获得某个属性对象
getDeclaredFields()获得所有属性对象

获取类中注解相关的方法(了解)

 获得类中构造器相关的方法(以下方法返回值为Constructor相关)

 获得类中方法相关的方法(以下方法返回值为Method相关)

方法用途
getMethod(String name, Class... parameterTypes)获得该类某个公有的方法
getMethods()获得该类所有公有的方法
getDeclaredMethod(String name, Class... parameterTypes)获得该类某个方法
getDeclaredMethods()

获得该类所有方法

  1. 反射程序示例  

                第一步自然是要获得当前要反射的类的Class对象,这里有三种

//第一种,使用 Class.forName("类的全路径名"); 静态方法。
//前提:已明确类的全路径名。
//第二种,使用 .class 方法。
//说明:仅适合在编译前就已经明确要操作的 Class
//第三种,使用类对象的 getClass() 方法

//以下是代码示例


class Student{
    //私有属性name
    private String name = "bit";
    //公有属性age
    public int age = 18;
    //不带参数的构造方法
    public Student(){
        System.out.println("Student()");
    }

    private Student(String name,int age) {
        this.name = name;
        this.age = age;
        System.out.println("Student(String,name)");
    }

    private void eat(){
        System.out.println("i am eat");
    }

    public void sleep(){
        System.out.println("i am pig");
    }
    private void function(String str) {
        System.out.println(str);
    }
    @Override
    public String toString() {
        return "Student{" +
        "name='" + name + '\'' +
        ", age=" + age +
        '}';
    }
}

public class TestDemo {
    public static void main(String[] args) {
    /*
    1.通过getClass获取Class对象
    */
    Student s1 = new Student();
    Class c1 = s1.getClass();
    
    /*
    2.直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
    这说明任何一个类都有一个隐含的静态成员变量 class
    */
    Class c2 = Student.class;
    
    /*
    3、通过 Class 对象的 forName() 静态方法来获取,用的最多,
    但可能抛出 ClassNotFoundException 异常
    */
    Class c3 = null;
    try {
        //注意这里是类的全路径,如果有包需要加包的路径
        c3 = Class.forName("Student");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    //一个类在 JVM 中只会有一个 Class 实例,即我们对上面获取的
    //c1,c2,c3进行 equals 比较,发现都是true
    System.out.println(c1.equals(c2));
    System.out.println(c1.equals(c3));
    System.out.println(c2.equals(c3));
    }
}

        在别的包里使用反射机制来获取Studentlei中的属性对象,构造方法和方法等;

//所有和反射相关的包都在 import java.lang.reflect 包下面
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectClassDemo {
    // 创建对象
    public static void reflectNewInstance() {
        try {
            Class<?> classStudent = Class.forName("Student");
            Object objectStudent = classStudent.newInstance();
            Student student = (Student) objectStudent;
            System.out.println("获得学生对象:"+student);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    // 反射私有的构造方法 屏蔽内容为获得公有的构造方法
    public static void reflectPrivateConstructor() {
        try {
            Class<?> classStudent = Class.forName("Student");
            //注意传入对应的参数
            Constructor<?> declaredConstructorStudent = 
                classStudent.getDeclaredConstructor(String.class,int.class);
            //Constructor<?> declaredConstructorStudent = classStudent.getConstructor();
            //设置为true后可修改访问权限    
            declaredConstructorStudent.setAccessible(true);
            Object objectStudent = declaredConstructorStudent.newInstance("张三",15);
            //Object objectStudent = declaredConstructorStudent.newInstance();
            Student student = (Student) objectStudent;
            System.out.println("获得私有构造哈数且修改姓名和年龄:"+student);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    // 反射私有属性
    public static void reflectPrivateField() {
        try {
            Class<?> classStudent = Class.forName("Student");
            Field field = classStudent.getDeclaredField("name");
            field.setAccessible(true);
            //可以修改该属性的值
            Object objectStudent = classStudent.newInstance();
            Student student = (Student) objectStudent;
            field.set(student,"小明");
            String name = (String) field.get(student);
            System.out.println("反射私有属性修改了name:"+ name);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    // 反射私有方法
    public static void reflectPrivateMethod() {
        try {
            Class<?> classStudent = Class.forName("Student");
            Method methodStudent =classStudent.getDeclaredMethod("function",String.class);
            System.out.println("私有方法的方法名为:"+methodStudent.getName());
            //私有的一般都要加
            methodStudent.setAccessible(true);
            Object objectStudent = classStudent.newInstance();
            Student student = (Student) objectStudent;
            methodStudent.invoke(student,"我是给私有的function函数传的参数");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        //reflectNewInstance();
        //reflectPrivateConstructor();
        //reflectPrivateField();
        reflectPrivateMethod();
    }
}


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

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

相关文章

研究生,但是一直摆烂——想办法解决

原因剖析 孤独因为没有朋友&#xff0c; 之前自己思维误区&#xff0c;总觉得好好学习好好锻炼变得优秀就会有朋友&#xff0c;其实不是这个样子的&#xff0c;即使自己一直内卷&#xff0c;但还是很孤独。 现在重新反思自己。 没有朋友因为&#xff1a; 1 外貌 2 聊天的情商…

Which programming language do you choose

NO.1&#xff1a;JavaScript JavaScript&#xff0c;简称JS语言&#xff0c;是一种具有函数优先的轻量级&#xff0c;解释型或即时编译型的高级编程语言。虽然它是作为开发Web页面的脚本语言而出名的&#xff0c;但是它也被用到了很多非浏览器环境中&#xff0c;JavaScript 基…

老王的自动驾驶决策和规划第一章

文章目录 自动驾驶决策规划算法序章第一章&#xff08;1&#xff09; 细说五次多项式&#xff08;2&#xff09; 凸优化与非凸优化(3) 直角坐标与自然坐标转换(上, 下) 自动驾驶决策规划算法 序章 课程链接&#xff1a;序章 第一章 &#xff08;1&#xff09; 细说五次多项…

关于SpringBoot整合Websocket实现简易对话聊天窗

前言 官网链接&#xff1a;Websocket Websocket 是什么&#xff1f;它可以将两个独立的浏览器窗口作为通信的两端。 这种形式的通信与传统的 HTTP、TCP 所不同。传统的 HTTP 请求—响应协议是无法实现实时通信的&#xff0c;也就是说&#xff0c;只能由客户端向服务端发送请求…

前端Web开发,HTML,css,JavaScript

web浏览器响应流程&#xff0c;及技术不同的浏览器&#xff0c;内核不同&#xff0c;对于相同的前端代码解析的效果会存在差异web标准&#xff0c;三个组成部分 HTML&#xff1a;负责网页的结构&#xff08;页面元素和内容&#xff09;CSS&#xff1a;负责页面的表现&#xff0…

VC调试方法大全

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

代码随想录算法训练营第四十八天| 198.打家劫舍、213.打家劫舍II、337.打家劫舍III

文章目录 198.打家劫舍213.打家劫舍II337.打家劫舍III 198.打家劫舍 题目链接&#xff1a;代码随想录 解题思路&#xff1a; 1.dp[i]&#xff1a;考虑下标i&#xff08;包括i&#xff09;以内的房屋&#xff0c;最多可以偷窃的金额为dp[i] 只是考虑&#xff0c;不一定偷 2.递推…

【STM32CubeMX】F103外部中断

前言 本文记录下我学习STM32CubeMX时的流程&#xff0c;方便以后回忆。系统板是基于STM32F103C6T6。本章记录外部中断。 步骤 该实验步骤以&#xff0c;配置PA1为外部中断下降沿触发事件&#xff0c;在触发事件后点亮板载PC13LED灯 时钟配置和生成文件配置之类的&#xff0c;其…

3.6 cache存储器

学习步骤&#xff1a; 我会采取以下几个步骤来学习Cache存储器&#xff1a; 确定学习目标&#xff1a;Cache存储器作为一种高速缓存存储器&#xff0c;通常用于提高计算机系统的运行效率。因此&#xff0c;我需要明确学习Cache存储器的目的&#xff0c;包括了解其原理、结构和…

No.054<软考>《(高项)备考大全》【冲刺8】《软考之 119个工具 (6)》

《软考之 119个工具 &#xff08;6&#xff09;》 99.应急应对策略:100.风险在评估:101.风险审计:102.偏差和趋势分析:103.技术绩效测量:104.自制或外购分析:105.市场调研:106.投标人会议:107.建议书评价技术:108.独立核算:109.广告:110.采购谈判:111.合同变更控制系统:112.采购…

定位图像坐标系和角度误区

坐标系和角度的常见误区 在学习halcon的时候.常常看文档的时候,会有一些地方比较疑感有些常用的地方有细微的差距,一不留意。就会导致计算的数据出错 常见的误区就在坐标系和角度 halcon的帮助情况 存在Px,Py 大家不要被搞混乱 Px -> Row Py-> Column 很多人定位项…

C语言——字符串及字符函数的介绍

C语言——字符串及字符函数的介绍 一、字符函数1.strlen1.1strlen的使用1.2strlen的三种模拟实现1.2.1计数器实现strlen函数1.2.2递归方法实现strlen函数1.2.3指针方法实现strlen函数 1.3 注意事项 2.strcpy2.1strcpy使用2.2strcpy的模拟实现2.3strcpy的注意事项 3.strcat3.1st…

【小样本分割 2022 ECCV】SSP

文章目录 【小样本分割 2022 ECCV】SSP摘要1. 介绍2. 相关工作3. 自支持小样本语义分割3.1 动机3.2 自支持原型-SSM3.3 自适应自支持背景原型-ASBP3.4 自支持匹配-SSL 3. 代码 【小样本分割 2022 ECCV】SSP 论文题目&#xff1a;Self-Support Few-Shot Semantic Segmentation 中…

SpringCloud 微服务系列——【Gateway、Config组件使用】

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

第二十三章 材质

3D模型主要是通过材质&#xff08;Material&#xff09;和贴图&#xff08;Texture&#xff09;来表现其精美的外表&#xff0c;说白了就是一张“画皮”而已。我们之前的DirectX课程中介绍过材质&#xff0c;它实际就是对光的反射率&#xff0c;这样简单的设置并不能展现3D模型…

Linux线程 概念、特点、线程间资源共享情况

1. 线程概念 线程是轻量级的进程&#xff1b;Linux中&#xff0c;线程本质上仍是进程。 进程是OS分配资源的最小单位&#xff0c;线程是OS调度的最小单位。 NPTL 当前Linux线程库为redHat开发的NPTL&#xff0c;查看本地线程库版本&#xff1a; getconf GNU_LIBPTHREAD_VE…

【C++】三元操作符、创建并初始化C++对象、C++new关键字

C的三元操作符 if的语法糖 例1 #include <iostream> #include <string>static int s_Level 1; static int s_Speed 2;int main() {if (s_Level > 5){s_Speed 10;}else{s_Speed 5;}std::cin.get(); }用三元操作符&#xff1a; s_Speed s_Level > 5 ?…

基础篇-并发篇

**63.线程状态 添加主线程和子线程 ** 65.线程状态 核心线程和任务队列都是有上限的&#xff0c;所以都满了话就开始使用救急线程; 救急线程也是有上限的&#xff0c;如果再来新的线程的话就需要拒绝策越; 注意&#xff1a;这里不需要等待5000ms&#xff0c;几乎是同时打印 注…

[230503] 2021年托福阅读真题第1篇|Grinding Grain 磨粒

11:21&#xff5e;11:41 慢 20min 正确率&#xff1a;6.5/10 题目来源&#xff1a;链接: https://pan.baidu.com/s/15FYCuD7__slfGvdsBIHgLQ 提取码: iynj --来自百度网盘超级会员v5的分享【内含2021年100篇托福阅读真题】 目录 Grinding Grain 题目 Grinding Grain It now…

2016 ICPC合肥站 传递 HDU-5961(拓扑排序 / bitset / 暴力(可hack))

题目链接&#xff1a;HDU-5961 传递 中文题面就不解释题目意思&#xff0c;解释一下名词的意思 完全图&#xff1a;对于一个无向图 G G G 而言&#xff0c;设点集为 V V V&#xff0c;点集中任意不相同两点 u , v u, v u,v 间都有且仅有一条边叫做完全图。 竞赛图&#xff1…