1、反射-概述(掌握)

反射就是在程序运行过程中,通过.class文件动态的获取类的信息(属性,构造,方法),并调用


注意:JAVA不是动态语言,因为动态语言强调在程序运行过程中不仅能获取并调用类里面的属性和方法,还要求能够给类增加属性和方法,而JAVA中的反射只能获取调用,不能修改类的结构

在反射中包含Declared的方法表示获取私有的成员内容,一般结合setAccessible(true)方法一起使用

2、创建Class文件的三种方式(掌握)

Class.forName("类全名");

          对象名.getClass();

          类名.class


          推荐使用:Class.forName("类全名");

3、获取构造方法并创建对象(掌握)

概述:
     java.lang.reflect.Constructor:构造方法操作类,通过该对象的newInstance方法能有创建构造方法
一、步骤
1、获取Class对象
2、通过调用getDeclaredConstructor或者getConstructor 方法创建构造器(Constructor)对象,如果构造方法没有形式参数写null
     public Constructor getDeclaredConstructor(形式参数1对应的.class对象, 形式参数2对应的.class对象....):该方法可以获取私有构造方法
     public Constructor getConstructor(形式参数1对应的.class对象, 形式参数2对应的.class对象....):该方法不能获取私有构造方法
3、如果获取到的是私有的构造方法的构造器对象,需要调用构造器对象的setAccessible(true)方法
4、通过构造器对象的newInstance(实际参数1, 实际参数2)创建对象,如果没有实际参数写null

二、举例
     1、通过private Person(String name, int age)创建对象
          
  1. Class clazz = Class.forName("com.itcast.Person");//必须通过类全名获取
  2. Constructor con = clazz.getDeclaredConstructor(String.class, int.class);//形式参数列表对应的.class列表
  3. con.setAccessible(true);//此处不设置,无法创建该对象,因为构造方法是私有的
  4. Object obj = con.newInstance("zhangsan",120);//调用newInstance(实际参数列表)创建对象


     2、通过public Person()创建对象
         
  1. Class clazz = Class.forName("com.itcast.Person");//必须通过类全名获取
  2. Constructor con = clazz.getDeclaredConstructor(null);//因为没有形式参数,所以写null
  3. con.setAccessible(true);//此处不设置,无法创建该对象,因为构造方法是私有的
  4. Object obj = con.newInstance();//因为不需要实际参数,所以调用无参的newInstance方法


4、获取属性并调用(掌握)

概述:
     java.lang.reflect.Field:属性操作类对象,可以对该类的对象的属性值进行修改和获取

一、步骤

     1、获取Class对象
     2、通过调用getDeclaredField("属性名")或通过调用getField("属性名") 获取属性操作类
     3、如果获取的是私有的属性,调用属性操作类的setAccessible(true)方法
     4、调用属性操作类的set(该类的对象,值) 来设置属性值
          调用属性操作类的get(该类的对象)来获取属性值

二、举例
          
  1. Person p1 = new Person();
  2. Person p2= new Person();
  3. Class clazz = Class.forName("Person");//第一步获取Class对象
  4. Field field = clazz.getDeclaredField("name");//第二步通过调用getDeclaredField("属性名")或通过调用getField("属性名") 获取属性操作类
  5. field.setAccessible(true);//第三步如果获取的是私有的属性,调用属性操作类的setAccessible(true)方法
  6. field.set(p1, "张三");//第四步用属性操作类的set(该类的对象,值) 来设置属性值
  7. field.set(p2, "李四");
  8. System.out.println(field.get(p1));//第四步调用属性操作类的get(该类的对象)来获取属性值
  9. System.out.println(field.get(p2));

     

5、获取成员方法并调用(掌握)

概述:

      java.lang.reflect.Method:方法操作类,可以执行该类的对象的方法

一、步骤
     1、获取Class对象
     2、通过调用getDeclaredMethod("方法名",形式参数1.class, 形式参数2.class..)或通过调用geMethod("方法名",形式参数1.class, 形式参数2.class..) 获取属性操作类,如果没有形式参数写null
     3、如果获取的是私有的方法,调用方法操作类的setAccessible(true)方法
     4、通过属性操作类的invoke(该类的对象,实际参数)来执行方法,如果没有实际参数写null

二、案例
          
  1.          Person p1 = new Person("张三",13);
  2. Person p2= new Person("李四",14);
  3. Class clazz = Class.forName("Person");
  4. /*
  5. * 调用setName方法
  6. */
  7. Method setName = clazz.getDeclaredMethod("setName", String.class);
  8. setName.setAccessible(true);//如果getName方法是私有的,此处必须写
  9. setName.invoke(p1, "张三改");
  10. /*
  11. * 调用getName方法
  12. */
  13. Method getName = clazz.getDeclaredMethod("getName", null); //获取Person类的getName方法对应的方法操作类
  14. getName.setAccessible(true);//如果getName方法是私有的,此处必须写
  15. Object object = getName.invoke(p1, null);//执行p1对象的getName方法,并且将返回值赋值给object
  16. System.out.println(object);

6、反射练习(掌握)

1:通过反射修改成员变量的值,包括私有
2: 通过反射运行配置文件
   在JAVA项目下新建配置文件confi.properties,内容为
     className=Person

name=jack


   JAVA代码:
          
  1.           Properties p = new Properties();
  2. p.load(new FileReader("config.properties"));
  3. String className = (String)p.get("class");
  4. String name = (String)p.get("nameName");
  5. Class clazz = Class.forName(className);
  6. //创建对象
  7. Constructor constructor = clazz.getConstructor(null);
  8. Object instance = constructor.newInstance();
  9. //通过setName设置name属性
  10. Method setName = clazz.getDeclaredMethod("setName", String.class);
  11. setName.invoke(instance,name );
  12. //通过getName设置name属性
  13. Method method = clazz.getDeclaredMethod("getName",null);
  14. Object object = method.invoke(instance, null);
  15. System.out.println(object);


3: 通过反射给 ArrayList<Integer>中添加String 类型的数据
  
  1.         ArrayList<Integer> list = new ArrayList<Integer>();
  2. list.add(123);
  3. Class clazz = Class.forName("java.util.ArrayList");//必须通过类全名获取
  4. Method method = clazz.getDeclaredMethod("add", Object.class);
  5. method.setAccessible(true);
  6. method.invoke(list, "ss");
  7. for(Object obj: list){
  8. System.out.println(obj);
  9. }

        

7、今天必须掌握的内容,面试题,笔试题。(掌握这个就可以放心学习后面的知识了)

1、什么是反射
2、说说通过反射如何操作属性
3、说说通过反射如何操作方法
4、说说通过反射如何操作构造方法
5、通过反射给 ArrayList<Integer>中添加String 类型的数据
6、通过反射运行config.propertis配置文件中的eat方法.配置文件信息如下
    className=cn.itcast.domain.Person
    methodName=eat









day27_反射的更多相关文章

  1. 隐私泄露杀手锏 —— Flash 权限反射

    [简版:http://weibo.com/p/1001603881940380956046] 前言 一直以为该风险早已被重视,但最近无意中发现,仍有不少网站存在该缺陷,其中不乏一些常用的邮箱.社交网站 ...

  2. Java学习之反射机制及应用场景

    前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框 ...

  3. 关于 CSS 反射倒影的研究思考

    原文地址:https://css-tricks.com/state-css-reflections 译者:nzbin 友情提示:由于演示 demo 的兼容性,推荐火狐浏览.该文章篇幅较长,内容庞杂,有 ...

  4. 编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议106~109)

    建议106:动态代理可以使代理模式更加灵活 Java的反射框架提供了动态代理(Dynamic Proxy)机制,允许在运行期对目标类生成代理,避免重复开发.我们知道一个静态代理是通过主题角色(Prox ...

  5. 运用Mono.Cecil 反射读取.NET程序集元数据

    CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...

  6. .NET面试题系列[6] - 反射

    反射 - 定义,实例与优化 在面试中,通常会考察反射的定义(操作元数据),可以用反射做什么(获得程序集及其各个部件),反射有什么使用场景(ORM,序列化,反序列化,值类型比较等).如果答得好,还可能会 ...

  7. .NET基础拾遗(4)委托、事件、反射与特性

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

  8. C++的性能C#的产能?! - .Net Native 系列五:.Net Native与反射

    此系列系小九的学堂原创翻译,翻译自微软官方开发向导,一共分为六个主题.本文是第五个主题:.Net Native与反射. 向导文链接:<C++的性能C#的产能?! - .Net Native 系列 ...

  9. [源码]Literacy 快速反射读写对象属性,字段

    Literacy 说明 Literacy使用IL指令生成方法委托,性能方面,在调用次数达到一定量的时候比反射高很多 当然,用IL指令生成一个方法也是有时间消耗的,所以在只使用一次或少数几次的情况,不但 ...

随机推荐

  1. Mysql Innodb 引擎优化-内存、日志、IO、其他相关参数

    介绍: InnoDB给MySQL提供了具有提交,回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎.InnoDB锁定在行级并且也在SELECT语句提供一个Oracle风格一致的非锁定读.这些特色增加 ...

  2. .net下开发ActiveX控件

    `   ActiveX 是一个开放的集成平台,为开发人员. 用户和 Web生产商提供了一个快速而简便的在 Internet 和 Intranet 创建程序集成和内容的方法. 使用 ActiveX, 可 ...

  3. 【FPGA】相关介绍

    什么是 FPGA ? FPGA是Field Programmable Gate Array的缩写,即现场可编程门阵列,它是在PAL.GAL.EPLD等可编程器件的基础上进一步发展的产物.它是作为专用集 ...

  4. 显示图片的(自定义)吐司Toast

    一般我们提示的时候都是直接提示文字的,其实Toast也可以显示图片 常用方法 Toast.makeText(context,text,duration)这返回一个Toast对象 toast.setDu ...

  5. 手机升级到iOS10,用Xcode7.3进行真机调试方法

    今天发布的正式版的iOS10,手机果断升级了,结果发现Xcode7.3不能真机调试了,原因是Xcode7.3里面没有iOS10的sdk,下面这个压缩包你可以下载下来放在你的Xcode7.3里面,当然了 ...

  6. PHP文件的读取

    1.PHP部分文件操作函数 ( fopen ,fread ,filesize,fwrite,fclose ) 2.unlink()  rmdir() 删除函数 unlink(路径和文件名): rmdi ...

  7. C++小项目:directx11图形程序(三):graphicsclass

    这是框架的第三层graphicsclass,这个类才真正可以说是整个程序的框架,因为它组织了后面所有的成员. 代码: graphicsclass.h #pragma once #include< ...

  8. Erlang&RabbitMQ服务安装配置

    RabbitMQ是流行的开源消息队列系统,是AMQP(Advanced Message Queuing Protocol高级消息队列协议)的标准实现,用erlang语言开发.RabbitMQ据说具有良 ...

  9. AngularJS时间轴指令

    是基于ion.rangeSlider.js,主要代码如下: <link rel="stylesheet" type="text/css" href=&qu ...

  10. 关于编程一些鲜为人知的真相 csdn

    <关于编程一些鲜为人知的真相>一文讲了一些编程的真相:如果把所有项目的生命周期平均一下,那么一个程序员大概10-20%的时间用来写代码,并且大多数程序员可能每天大约只有10-12行代码会进 ...