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. 微信开发订阅号(ASP.NET MVC4+jquery mobile+AppHarbor发布)

    首先应该去微信公众平台注册一个账号,因为我是用的个人,所以只能注册订阅号,然后需要提供身份证照片,这些大家慢慢折腾.然后在微信管理面板中选择高级功能,进入开发者模式. 在服务器配置中需要提供最重要的u ...

  2. TEA(Tiny Encryption Algorithm)

    简介 TEA是一种简单高效的加解密算法,以速度快,实现简单著称.TEA算法每一次可以操作64-bit数据,采用128-bit作为key,算法采用迭代的形式,推荐的迭代轮数是64,最少32. 代码(默认 ...

  3. iOS中 HTTP/Socket/TCP/IP通信协议详解

    // OSI(开放式系统互联), 由ISO(国际化标准组织)制定 // 1. 应用层 // 2. 表示层 // 3. 会话层 // 4. 传输层 // 5. 网络层 // 6. 数据链接层 // 7. ...

  4. iOS UIView上添加mp4视频

    ViewController.h文件中添加如下代码: #import <MediaPlayer/MediaPlayer.h> @property(nonatomic,retain) MPM ...

  5. Fake chat script for website download

    Are you searching for free fake webchat script then you are at the right place go get download your ...

  6. GDB中汇编调试

    GDB中汇编调试 1.输入代码 2.使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,时遇到问题使用-m32指令报错,参考卢肖明同学博客知道这是 ...

  7. zookeeper集群安装与配置

    转自: http://my.oschina.net/u/2377453/blog/464739 1.解压zookeeper 2.在$ZOOKEEPER_HOME/conf下创建zoo.cfg文件(参考 ...

  8. AngularJs的UI组件ui-Bootstrap分享(十四)——Carousel

    Carousel指令是用于图片轮播的控件,引入ngTouch模块后可以在移动端使用滑动的方式使用轮播控件. <!DOCTYPE html> <html ng-app="ui ...

  9. AngularJs的UI组件ui-Bootstrap分享(八)——Tooltip和Popover

    tooltip和popover是轻量的.可扩展的.用于提示的指令.对于移动端来讲,这两个指令虽然可以正常工作,但是从用户体验的角度并不推荐使用. 先说tooltip,tooltip有三种使用方式: ( ...

  10. PreparedStatement

    PreparedStatement > 它是Statement接口的子接口: >强大之处: 防SQL攻击: 提高代码的可读性.可维护性: 提高效率! l 学习PreparedStateme ...