您的位置:首页 > 编程语言 > Java开发

java高新技术之反射

2013-01-29 10:18 260 查看
学习思路:
认识Class类——>了解反射的主要组成部分——>了解类中的各个方法

一 1 Class 类是什么?

可以用来表示并获取java类的某一属性的类



2 class获取文件字节码的方式以及适用场合

定义java类获取class类字节码文件的方式有3种:

class cls1 = 类名.class;

class cls2 = 实例对象名.getClass();

class cls3 = Class.forName("");

3 预定义class数据类型字节码文件;

8个基本数据类型.clas加上void.class

判断类型是否为原始类型,判断类型是否为数组;



4 什么是反射?反射就是把java中的各个部分映射成相应的java类;



5 在java中各个不同组成对应的java类中方法:

常用来获取java类中方法,变量,构造函数,修饰符,包的类有:

Method,Constructor,Package,.Field

A Constructor:

a (1)得到所有的构造方法:

Constructor[] 变量名 = 字节码.getConstructors();

(2)得到一个构造方法

Constructor 变量名 = 字节码.getConstructor(/*有参数时这里写参数的“数据类型.class”,没有就不用写);

比较普通与反射创建对象的不同

b 如何使用构造方法

构造方法的实例变量.newInstance()//有的话,到()里面写参数(对象)

注意,因为Construct,所以要强制类型,再赋值给变量

如:

Constructor constructor1 = String.class.getConstructor(StringBuffer.class);

String str1 = (String)constructor1.newInstance(new StringBuffer("agbc"));

c 如果通过Class.newInstance()会更加快!



B Field:(与Constructor类似)

a 得到多个成员变量

Field[] fileds = 字节码.getFields();

b 取其中一个

Field field = 字节码.getField("x");//括号中是要获得的变量

打印的时候注意要用get方法获取:

System.out.println(field.get(field));

上面说的都是针对public类型的,那如何对private类型的操作呢?

c 取私有的成员变量

Field fieldx = 字节码文件.getDeclaredField("x")//变量在()里面

fieldx.setAccessible(true);//强制使可以获取

System.out.println(field.get(fieldx));

练习:

将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改为"a";



思路:

步骤一:定义一个包含多个字符串成员变量;

步骤二:在使用这个类的方法中获取该类的Filed实例对象即字节码文件。

因为有多个,可以使用getFields()方法获取所有的成员变量(有私有的话,就调用getDeclaredFields)。

步骤三:获取了成员变量之后,遍历,判断是否含有成员变量为String.class的field对象;

步骤四:如果存在,就获得该String类型对象,并保存到一个变量中;

步骤五:使用replace方法,将所有的“b”换为“a”,并返回给一个新的String类型变量

步骤六:使用set()方法,替换变量的值。

步骤七:输出查看改变后的变量的值。

问题,getFields()是否可以获得所有的成员变量,不管是public还是private

C Method

a 获取某一个方法:

Method method = 字节码.getMethod(String name,参数列表类型(如int.class))

使用方法:method.invoke(str1,1)(注:str1为字符串对象,把str1改为null后,就为静态方法了)

JDk 1.4与JDK1.5的区别:

JDK1.4 public Object invoke(Object obj,Object[] args)

JDK 1.5 public Object invoke(Object obj,Object...args)

练习:

写一个程序,这个程序能够根据用户提供的类名,去执行类中的main方法。

思路:

关键弄清楚main函数如何进行参数传递,传递的是什么这个问题。

D 数组的反射

(1)数组基础

a 数组的字节码文件,他们的父类都是Object(具有相同类型和维数的数组字节码文件相同);

b 通过字节码文件实例对象调用getSuperclass方法可以得到父类的Object类对应的Class

c 如何通过数组直接输出数组内容(Arrays.asList(实例对象名)):

d 基本类型的一维数组可以被当做Object类型使用,不能当做Object[]使用,非基本数据类型的

一维数组既可以当Object类型使用,又可以当做Object[]类型使用。

(2)

数组反射

a 判断是否为数组类型的字节码文件:isArray();

b 如何获取该字节码文件数组的类型



HashSet类中,不要改变参与哈希地址计算的的量(更改后,就删不掉,内存泄露)



二 java反射及框架原理

java框架原理不是很清楚。原因:对于框架中一些方法等不清楚

IntroSpector(检查视察,内省)——>javaBean操作-->特殊java类

JavaBean特征:

1,命名;符合某一种特殊命名规则的java类;public int getAge()

get,set后面的单词,根据第二个字母决定属性名称是大写还是小写

如:getCPU()--》CPU

getTime()--》time

2 通过反射的方式使用javaBean中的get和set方法以及重构方法



PropertyDescriptor pd = new PropertyDescriptor(propertyName,需要提取get或set方法的字节码文件);

(1)Method methodGetX = pd.getReadMethod();//获取对应属性读的方法

Object retVal = methodGetX.invoke(pt1);//方法与对象相关联



set方法类似

(2)Method methodX = pd.getWriteMethod();

methodGetX.invoke(pt1,value);//value为进行设置的属性的值



重构方法:

选中要重构的代码,右键,选中Refactor——》Extract Method-->按提示操作;



3 通过遍历所有的BeanInfo方式,查找某一个属性方法

首先,获取指定Bean对象信息的封装类:BeanInfo beanInfo = new BeanInfo(pt1.getClass());

接着, 获取指定对象的所有封装属性 PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();

遍历属性,获取指定属性的读取值:



for(PropertyDescriptor pd:pds)
     {
      if(pd.getName().equals(propertyName))
      {
       Method methodGetX = pd.getReadMethod();
       retVal = methodGetX.invoke(pt1);
       break;
       }
     }

  PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClas());
  Method methodGetX = pd.getReadMethod();
  Object retVal = methodGetX.invoke(pt1);


总结,获取属性用下面这种,也就是2方式那种。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: