在张孝祥老师的Java讲解中,学习到了Java反射的一部分知识,觉得有必要好好学习一下哈。

一、反射的理解

经典总结:反射就是把Java类中的各种成分映射成为相应的Java类

例如:一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量、方法、构造方法、包等信息也用一个个的Java类来表示,表示Java类中的Class类显然要提供一系类的方法,来获得其中的变量、方法、构造方法、修饰类、包等信息,这些信息就是用相应的实例对象来表示,它们是Field、Method、Contructor、Package等

反射的缺点:反射导致程序性能下降

二、构造方法(Constructor)反射

理解:就是获取到某一个Class类中的所有的构造方法Constructor类

  1. // 获得某个类的所有的构造方法
  2. Constructor[] constructors = Class.forName("java.lang.String").getConstructors();
  3.  
  4. // new String(new StringBuffer("abc"))
  5. // 得到String类的某一个构造方法
  6. Constructor constructor = String.class.getConstructor(StringBuffer.class);
  7. String str2 = (String) constructor.newInstance(new StringBuffer("abc"));

三、成员变量(Field)反射

理解:获取一个Class类中的成员变量的Field,以及通过反射获取其中某一个对象的成员变量的值

  1. public class ReflectPoint {
  2.  
  3. private int x;
  4. public int y;
  5.  
  6. public ReflectPoint(int x, int y) {
  7. super();
  8. this.x = x;
  9. this.y = y;
  10. }
  11. }
  12.  
  13. ReflectPoint rf1 = new ReflectPoint(3, 5);
  14. // 获取Class类的Field成员变量,并没有指定是哪个对象的 fieldY不是对象上的变量,而是Class类上的变量,要用他去取某个对象上的值
  15. Field fieldY = rf1.getClass().getField("y");
  16. // 获取rf1这个对象的成员变量的值
  17. Object obj = fieldY.get(rf1);
  18. System.out.println(obj);
  19.  
  20. // 获取Class类的Field成员变量,并没有指定是哪个对象的 这里x是私有的属性,但是也可以通过反射暴力获得
  21. Field fieldX = rf1.getClass().getDeclaredField("x");
  22. // 暴力反射
  23. fieldX.setAccessible(true);
  24. // 获取rf1这个对象的成员变量的值
  25. Object objX = fieldX.get(rf1);
  26. System.out.println(objX);

注意:其中的注解也写的比较清楚,但是还想强调一下,Field类只是获取到了字节码中的成员变量,但是并没有获取到某一个特定对象的成员变量的具体的值

成员变量反射的综合案例:

题目:将任意一个对象中所有的String类型的成员变量所对应的字符串中的“b”转化成“a”,这其中用到了成员变量的反射,具体代码如下所示

  1. public class ReflectPoint {
  2.  
  3. private int x;
  4. public int y;
  5. public String str1 = "ball";
  6. public String str2 = "basketball";
  7. public String str3 = "itcast";
  8.  
  9. public ReflectPoint(int x, int y) {
  10. super();
  11. this.x = x;
  12. this.y = y;
  13. }
  14. }
  15.  
  16. private static void changeStringValue(Object obj) throws Exception {
  17. Field[] fields = obj.getClass().getFields();
  18. for(Field field: fields){
  19. //if(field.getType().equals(String.class)){
  20. //这里就直接用 == 比较在内存中编译的字节码文件
  21. if(field.getType() == String.class){
  22. String oldValue = (String) field.get(obj);
  23. String newValue = oldValue.replace('b', 'a');
  24. field.set(obj, newValue);
  25. }
  26. }
  27. }

总结:其实这种反射的应用在spring框架的源码中应该是挺常见的,有时间去看看spring的源码,我想真正懂了反射的原理之后,再去读spring的源码的话,会轻松很多的!

四、成员方法(Method)类

理解:可以获取一个类中的成员方法

  1. String str1 = "abc";
  2.  
  3. Method methodCharAt = String.class.getMethod("charAt", int.class);
  4. // 注意这个invoke方法,这个是调用的意思,就是这个方法调用执行,传入new出来的对象以及参数
  5. System.out.println(methodCharAt.invoke(str1, 1));
  6. // 如果是静态方法的话,是不用传入new 出来的对象的,只需要传入参数即可
  7. // System.out.println(methodCharAt.invoke(null, 1));

注意:静态方法,直接传入null即可,因为静态方法都是放在方法区中的,对象在栈中创建出来,就可以直接调用

高能:用反射方式执行某个类中的main方法(写个程序,根据用户提供的类名,去执行该类中的main方法)

为什么我很费劲的去用反射区调用main方法呢,这里其实可以引出一个前提条件,就是我并不知道到底是哪个类的main方法,但是类名可能就存在传递的参数中,我通过得到参数,得到类名,然后通过反射,启动main方法???

  1. static class TestArguments{
  2. public static void main(String[] args) {
  3. for(String arg:args){
  4. System.out.println(arg);
  5. }
  6. }
  7. }
  8.  
  9. //TestArguments.main(new String[]{"111","222","333"});
  10. String startingClassName = args[0];
  11. Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
  12. mainMethod.invoke(null, (Object) new String[]{"111","222","333"});
  13.    //mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});

五、数组(Array)反射

直接上代码吧,数组的反射应该在开发框架中会得到使用,直接看一下简单的代码吧,当然那个Array是java中的reflect包中的类:java.lang.reflect.Array

  1. private static void printObject(Object obj1) {
  2. Class clazz = obj1.getClass();
  3.  
  4. if(clazz.isArray()){
  5. int len = Array.getLength(obj1);
  6. for(int i=0;i<len;i++){
  7. System.out.println(Array.get(obj1, i));
  8. }
  9. }else{
  10. System.out.println(obj1);
  11. }
  12. }
  13.  
  14. printObject(obj1);
  15. printObject(new int[]{1,2,3});

Java中的反射--Reflect的更多相关文章

  1. Java中的反射和注解

    前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...

  2. 浅说Java中的反射机制(二)

    写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编 ...

  3. 浅说Java中的反射机制(一)

    在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...

  4. java中动态反射

    java中动态反射能达到的效果和python的语法糖很像,能够截获方法的实现,在真实方法调用之前和之后进行修改,甚至能够用自己的实现进行特别的替代,也可以用其实现面向切片的部分功能.动态代理可以方便实 ...

  5. java笔记十:java中的反射

    Java中,反射是一种强大的工具.它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接.反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM中的类的内部信息,而 ...

  6. 【Java基础】java中的反射机制与动态代理

    一.java中的反射机制 java反射的官方定义:在运行状态下,可以获取任意一个类的所有属性和方法,并且可通过某类任意一对象实例调用该类的所有方法.这种动态获取类的信息及动态调用类中方法的功能称为ja ...

  7. java中使用反射获取pojo(实体)类的全部字段值

    说起反射.不得不说它实在是太强大了,通过反射就能够轻轻松松拿到各种东东,假设你想在项目中解除对某个类的依赖,能够考虑用反射. 今天跟大家分享的是通过java中的反射,获取pojo类的全部字段值. 为什 ...

  8. java 中利用反射机制获取和设置实体类的属性值

    摘要: 在java编程中,我们经常不知道传入自己方法中的实体类中到底有哪些方法,或者,我们需要根据用户传入的不同的属性来给对象设置不同的属性值,那么,java自带的反射机制可以很方便的达到这种目的,同 ...

  9. java中的反射(三)

    目录 一.反射 1.class类 2.访问字段 3.调用方法 4.调用构造方法 5.获取继承对象 6.动态代理 二.sping中的反射 本篇转自:https://depp.wang/2020/05/0 ...

随机推荐

  1. mysql5.7根据.frm和.ibd文件恢复表结构和数据

    一.恢复表结构 1.环境:Windows .mysql5.7:首先创建一个数据库,可以通过navicat来创建:     2.使用当前创建的数据库:use ww; 3.随意创建一张表,但是这张表的名字 ...

  2. Git分布式版本控制工具

    一.安装Git  1.下载Windows版的Git:msysgit:官方下载地址:http://msysgit.github.io,安装选定要安装的目录(路径杜绝中文),剩下的按照默认安装即可,参考: ...

  3. HDOJ1584蜘蛛牌【DFS】

    10张牌,大的只能跟小的跑,可以针对每一个状态进行搜索,求一个最小的移动距离. 但是不会怎么遍历整个状态是硬伤? 因为只能大的跟着小的. 先把小的标记,去寻找大的点,最终一定是满足的吧. 比如先标记1 ...

  4. sql server编写通用脚本自动统计各表数据量心得

    工作过程中,如果一个数据库的表比较多,手工编写统计脚本就会比较繁琐,于是摸索出自动生成各表统计数据量脚本的通用方法,直接上代码: /* 脚本来源:https://www.cnblogs.com/zha ...

  5. MapperException: 无法获取实体类xxxxx对应的表名! 三种解决方法,总有一款适合你。

    先把自动重启关一下 devtools: restart: #热部署生效 enabled: false 把devtools给删除了,说是这个jar包导致 ApplyApplication里面的@Mapp ...

  6. Codeforces 1144F(二分染色)

    发现奇环不可行,偶环可行,考虑二分图.然后染色,方向全都从一种指向另一种就可以了,随意. ; int n, m, color[maxn]; vector<int> vc[maxn]; ve ...

  7. Cake slicing UVA - 1629

    UVA - 1629 ans[t][b][l][r]表示t到b行,l到r列那一块蛋糕切好的最小值d[t][b][l][r]表示t到b行,l到r列区域的樱桃数,需要预处理 #include<cst ...

  8. JSP文件过大无法编译

    JSP文件过大无法编译: The code of method _jspService(HttpServletRequest, HttpServletResponse) is exceeding th ...

  9. Oozie的作用

    Oozie的作用: 1.统一调度hadoop系统中常见的mr任务启动. hdfs操作. shell调度. hive操作等 2.使得复杂的依赖关系.时间触发.事件触发使用xml语言进行表达,开发效率提高 ...

  10. 洛谷P2762 太空飞行计划问题(最大权闭合图)

    题意 有$m$个实验,$n$中器材,每个实验需要使用一些器材 每个实验有收入,每个器材有花费 最大化收入 - 花费 Sol 最大权闭合图的经典应用 从$S$向每个实验连流量为该实验收入的边 从每个器材 ...