反射
一、反射就是把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比普通类的方式更方便。
浙公网安备 33010602011771号