反射

一、反射就是把Java类中的各种成分映射成相应的Java类。例如:一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造函数,包等信息,也用一个个的Java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示Java类的Class类显然要提供一系列的方法来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,他们是Field、Method、Constructor、Package等等。

二、一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象,得到这些实例对象有什么用呢?怎么用呢?这正是学习和应用反射的要点。

Constructor类

1、Constructor类代表某个类中的一个构造方法。

2、得到某个类所有的构造方法:

例子:Constructor[]  constructors = Class.forName("java.lang.String").getConstructors();

3、得到某个类中的一个构造方法:

例子:Constructor  constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);

4、创建实例对象

通常方法:String str = new String(new StringBuffer("abc"));

反射方法:String str =(String)constructor.newInstance(new StringBuffer.class);

//调用获得的方法时需要用到上面相同类型的实例对象。

5、Class.newInstance()方法

例子:String obj = (String)Class.forName("java.lang.String").newInstance();

该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。

该方法内部的具体代码是怎么写的呢?用到了缓存机制来保存默认构造方法的实例对象。

 

Field类

1、Field类代表某个类中的一个成员变量。

2、演示用eclipse自动生成Java类的构造方法

3、问题:得到的Field对象时对应到类上面的成员变量,还是对应到对象上的成员变量?

类只有一个,而该类的实例对象有多个。如果是与对象关联,那关联的是哪个对象呢?

所以字段fieldX代表的是x的定义,而不是具体的x变量。

 

Method类

1、Method类代表某个类中的一个成员方法。

2、得到类中的某个方法

例子:Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.class);

3、调用方法

通常方法:System.out.println(str.charAt());

反射方法:System.out.println(charAt.invoke(str,1));

如果传递给Method对象的invoke()方法的一个参数为null,这有什么意义呢?

说明该method 对象对应的是一个静态方法。

 

二、反射的作用:

 反射的作用是实现框架功能。

1、框架与框架要解决的核心问题

我卖房子给用户住,由用户自己安装门窗和空调,我做的房子就是框架,用户需要使用我的框架,吧门窗插入进我提供的框架中,框架与工具类有区别,工具类被用户的类调用,而框架则是调用用户提供的类 。

2、框架要解决的核心问题

  1---我在写框架(房子)时,你这个用户可能还在上小学,还不会写程序呢?我写的框架程序怎样调用到你以后写的类(门窗)呢?

  2---因为我在写程序时,无法知道要被调用的类名,所以,在程序中无法直接new某个类的实例对象,而要用反射方式来做。

3、综合案例

  1---先直接用new语句创建ArrayList和HashSet的实例对象,演示用Eclipse自动生成ReflectPoint类的equals和HashCode方法,比较两个集合的运行结果差异。

  2---然后改为采用配置文件夹反射的方式创建ArrayList和HashSet的实例对象,比较观察运行结果差异。

 

 

内省

内省对应的英文单词为IntroSpector,它主要用于对JavaBean进行操作。

1、JavaBean是一种特殊的Java类,主要用于传递数据信息,这种Java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。

2、如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问,大家觉得这些方法的名称叫什么好呢?JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量,如果方法名为setId,中文意思即是设置id,至于你把它存在那个变量上,用管吗?如果方法名为getId,中文意思即是获取id,至于你从那个变量上取的,用管吗?去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。

setId()的属性名-----id;

isLast()的属性名----last;

setCPU()的属性名-----CPU;

getUPS()的属性名-----UPS;

总之,一个类被当作JavaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到Java类内部的成员变量。

 

一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当JavaBean用肯定需要带来一些额外的好处,我们才会去了解和应用JavaBean。好处如下:

1、在JavaEE开发中,经常要用到JavaBean,很多环境就要求按JavaBean方式进行操作,别人都这么用和要求,那你就没什么挑选的余地了。

2、jdk中提供了对JavaBean进行操作的一些api,这套API就成为内省,如果要你自己去通过getX方法访问私有的x,怎么做,有一定难度吧!用内省这套API操作JavaBean比普通类的方式更方便。

posted on 2015-07-24 20:36  huihui10  阅读(125)  评论(0)    收藏  举报

导航