`
cdzm5211314
  • 浏览: 8161 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

反射概念与应用

 
阅读更多
透彻分析反射的基础_Class类
  Class类:Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class
  如何得到各个类的字节码,即Class类?
  1、类名.class //直接使用类.class获得
  2、对象.getClass()//通过对象调用其getClass方法
  3、Class.forName(“java.util.Date”) //使用类加载器加载
  Java原始基本类型:boolean, byte, char, short, int, long, float,double 和关键词 void同样都有Class类,通过.class可获得他们的类字节码
理解反射的概念
  反射就是吧Java类中的各种成分映射成相应的Java类,例如一个Java类中用一个Class类的对象表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就想七成是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示Java的Class类显然要提供一系列的方法,来获得其中的变量、方法、构造方法,修饰符、包等信息,这些信息就是用相应的类的实例对象来表示,他们是Field、Method、Contructor、Package等等。
  一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示。
构造方法的反射应用  
  Constructor 类,各种类的构造方法的反射类。
  Constructor 反射类对象的获得:
  例:Constructor constructor=String.class.getConstructor(StringBuffer.class);
  构造方法可以用于构造实例对象
  String str=(String)constructor.newInstance(new StringBuffer("abc"));
  Class本身也还有newInstance方法,可以直接调用,例如
  String obj=(String)String.class.newInstance();
  //类似于调用无参的构造方法。
成员变量的反射
  Field 类,类中成员变量的反射类。
  Field 对象的反射获得:
  class Person
  {
    public String personname;
    protected String personcity;
    private String personadd;
    public int personage;
    public Person(String personname, String personcity, String personadd)
    {
      this.personname = personname;
      this.personcity = personcity;
      this.personadd = personadd;
      this.personage=0;
    }
  }
  ...... 
  //一下为Field反射类的应用部分
  ...... 
  Person person=new Person("myname","mycity","myaddress");
  Field fieldname=person.getClass.getField("personname");//基本方式获得public成员变量
  Field fieldcity=person.getClass.getDeclaredField("personcity");//获得声明的成员变量
  Field fieldadd=person.getClass.getDeclaredField("personadd");//获得声明的成员变量
  //Field[] fields=person.getClass.getDeclaredFields();//获得声明的所有成员变量数组  
  System.out.println("personname:" + fieldname.get(person));//打印成员变量的值
  System.out.println("personcity:" + fieldcity.get(person));//protect修饰变量可直接读取
  personadd.setAccessible(true);//设置成员变量可访问,包括private成员变量(暴力反射)
  System.out.println("personcity:" + fieldadd.get(person));//private成员必须设置访问权限setAccessible(true)后才可以访问
  成员变量的修饰符public、protect、private对反射类有不同的权限要求,注意红色字体部分。
成员变量反射的综合案例
  循环访问类示例对象的成员变量,并修改其变量值:
  public class Java_Test  //声明运行主体类
  {
    public Java_Test()
    {
      // TODO Auto-generated constructor stub
    }
    public static void main(String[] args) throws Exception
    {
      System.out.println("-------------------------------");
      Person person=new Person("myname","mycity","myaddress");
      System.out.println(person.toString());  //打印原始对象成员变量的值
      System.out.println("-------------------------------");
      chageFields(person);  //调用方法访问并修改类成员变量的值
      System.out.println(person.toString());  //打印修改后的成员变量值
      System.out.println("-------------------------------");
    }
    public static void chageFields(Object obj) throws IllegalAccessException
    {
      String str;
      Field[] fields=obj.getClass().getDeclaredFields();  //获得成员变量反射类对象数组
      for(Field field:fields)  //循环访问数组成员
      {
        field.setAccessible(true);  //设置成员变量可访问(暴力反射)
        if(field.getType()==String.class)
        {
          str=(String)field.get(obj);  //读取成员变量的值
          str=str.replace('_',' ');  //修改
          field.set(obj,str);  //重新设置成员变量的值
        }
      }
    }
  }
  class Person  //声明要操作的类
  {
    public String personname;
    protected String personcity;
    private String personadd;
    public int personage;
    public Person(String personname, String personcity, String personadd)
    {
      this.personname = personname;
      this.personcity = personcity;
      this.personadd = personadd;
      this.personage=0;
    }
    @Override  //覆盖toString方法,显示成员变量的值
    public String toString()
    {
      return "personname:" + personname +"\npersoncity:"+personcity + "\npersonadd:" + personadd;
    }
  }
成员方法的反射  
  Method 类,类中各个成员方法的反射类
  成员方法的反射应用方法:先得到类字节码的方法,然后再指定在哪个对象上调用方法,最后进行调用。
  例如:利用反射调用String类的charAt方法
  String str=new String("abc")
  Method methodCharAt=String.class.getMethod("charAt",int.class);
  //注意参数类型及意义:类字节码class.getMethod(“方法名”,方法参数类型.class)
  System.out.println(methodCharAt.invoke(str,1));  //方法对象.invoke(原对象,参数对象数组)
  输出结果同直接调用对象方法,即:str.charAt(1)
  *注意* 静态方法的反射调用可以写成:方法对象method.invoke(null,参数对象数组)
      无参静态方法反射调用要写成:方法对象method.invoke(null,null)
      JDK1.4版本注意参数类型构成:methodCharAt.invoke(str,new Object[]{1})
对接收数组参数的成员方法进行反射
  示例:调用其他类的main方法 public static void main(String[] args)
  String mainClassName=new String("MainClassName");
  Method mainMethod=Class.forName(mainClassName).getMethod("main", String[].class);
  mainMethod.invoke(null, new Object[]{new String[]{"Ling","Dong","Cao"}});
  mainMethod.invoke(null, (Object)new String[]{"Ling","Dong","Cao"});
  为兼容JDK1.4,invoke会将数组参数拆分为单个的元素来作为参数列表。在以上示例中如果直接使用数组作为参数,则会出现main方法参数个数错误:
  //错误的写法:mainMethod.invoke(null,new String[]{"Ling","Dong","Cao"});
数组与Object的关系及其反射类型
  1、具有相同维数和元素类型的数组属于统一个类型,即具有相同的Class实例对象
  2、代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class。
  3、基本类型的一维数组可以被当做Object类型使用,不能当做Object[]类型使用,非基本类型的一维数组既可以当做Object类型使用,又可以当做Object[]类型使用。
  示例:
  int[] num1=new int[3];
  int[] num2=new int[4];
  int[][] num12=new int[3][4];
  String[] str=new String[3];
  下面说明各个对象的反射类的关系
  num1.getClass()==num1.getClass()
  num1.getClass()!=num12.getClass()
  num1.getClass()!=str.getClass()
  数组与Object的关系:
  num1.getClass().getSuperClass().getName()==str.getClass().getSuperClass().getName()=="java.lang.Object"
  Object objint1=num1;
  Object objint12=num12;
  Object objstr=str;
  //Object[] objint=num1;  //错误的写法,int基本类型不是Object
  Object[] objint12=num12;  //正确写法,因其成员为int[],为Object。
  Object[] obj_str=str;  //正确,因为String实例即为Object对象类型
  Array.asList()方法处理int[]和String[]的差异。
  int[] num=new int[]{1,2,3};
  String[] str=new String[]{"aaa","bbb","ccc"};
  System.out.println(Arrays.asList(num1));  //打印输出类似“[[I@c17164]”的字符
  System.out.println(Arrays.asList(str));  //打印类似“[aaa, bbb, ccc]”的字符
数组的反射应用
  打印传入对象,如果为单一对象,直接打印,如果为数组,则逐一打印数组元素(对数组对象的判断应用)
  public void printObject(Object obj)
  {
     Class cla=obj.getClass();
     if(cla.isArray())
     {
      int len=Array.getLength(obj);
      for(int i=0;i<len;i++)
      {
        System.out.println(Array.get(obj,i));
      }
     }
     else
     {
       System.out.println(obj);
     }
  }
分享到:
评论

相关推荐

    java中反射的概念

    这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。其中LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基于反射机制的语言。...

    反射的概念及应用(C#)

    详细介绍反射的概念,并以C#为例子进行说明

    C#中反射的应用小结

    反射是C#的一个重要概念,如何使用很重要,有必要抽时间好好学习一下!

    JAVA新特性--java反射、映射

    反射本身并不是一个新概念,它可能会使我们联想到光学中的反射概念,尽管计算机科学赋予了反射概念新的含义,但是,从现象上来说,它们确实有某些相通之处,这些有助于我们的理解。在计算机科学领域,反射是指一类...

    论文研究-电磁波发生全反射现象的研究及应用 .pdf

    电磁波发生全反射现象的研究及应用,施鹄,郝宏刚,本文通过引入狭义全反射和平衡场等概念,对电磁波的全反射现象和光纤传输问题进行建模,深入分析了发生全反射时折射波(表面波)

    java泛型和反射机制

    对java泛型以及反射机制进行原理和应用上的讲解,帮助初学者对这两个概念进行更轻松的掌握

    遥感技术应用课件:遥感概念及特点.pptx

    应用探测仪器,不与探测目标接触,从远处用把目标的电磁波特性记录下来,通过对信息的处理和分析研究,揭示出物体的特征、性质及其变化的综合性探测技术。 戈壁滩遥感影像 戈壁滩遥感影像 遥感的基本概念 遥感技术...

    C#反射参考

    学习笔记整理,里面简单介绍了反射的概念及应用相关。

    PHP进阶学习之反射基本概念与用法分析

    本文实例讲述了PHP进阶学习之反射基本概念与用法。分享给大家供大家参考,具体如下: 一、前言 Reflection(反射)是Java程序开发语言的特征之一,它允许运行中的Java程序对自身进行检查,或者说“自审”,并能直接...

    Java反射机制(推荐)

    反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。

    visual basic.net 反射参考手册

    本书全面介绍了反射的概念及其相关应用技术,内容包括使用动态绑定的原因以及Reflection API支持它的方式;检测程序集类等元数据;自由加载程序集并创建对象和调用方法;利用反射修改对象数据;使用属性控制编译过程...

    Java 反射机制浅析

    Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和...这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

    Java反射机制

    这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。其中LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基于反射机制的语言。...

    学习笔记之反射

    介绍反射的概念及初步的应用,有实例.

    ES6 如何改变JS内置行为的代理与反射

    代理(Proxy)可以拦截并改变 JS 引擎的底层操作,如数据读取、属性定义、函数构造等一系列操作。ES6 通过对这些底层内置...如果你对些代理&反射的概念比较困惑的话,可以直接看后面的应用示例,最后再重新看这些定义

    Java高级程序设计实战教程第三章-Java反射机制.pptx

    对于任意一个对象,都能够调用它的任意一个方法,常见的应用如下 逆向代码 ,例如反编译 与注解相结合的框架 例如Retrofit 单纯的反射机制应用框架 例如EventBus 2.x 动态生成类框架 例如Gson Java高级程序设计实战...

    一个关于反射的简单示例

    一个关于反射的简单示例。可以从理解反射的概念开始,结合示例,分析反射的应用范围。很快就可以真正理解反射机制了。

    C#(2.0)反射例子(VS 2005)

    一个VS 2005下执行成功的关于反射的例子。有助于提高学习反射的概念和应用!附带数据!

    PHP反射原理与用法深入分析

    说到反射,实际上包含两个概念: 检视 introspection 判断类、方法是否存在,父子类关系,调用关系等,检视的函数文档 反射 Reflection 获取类里的方法、属性,注释等,反射类的文档 PHP官方文档写得很清晰了,...

Global site tag (gtag.js) - Google Analytics