AdaultBird--我的黑马程序员之路!Chapter10---java反射!

来源:互联网 发布:北京弘力乐器淘宝店 编辑:程序博客网 时间:2024/06/05 17:46

2015年9月10日,今天学习到反射第23节,学习的内容有java反射、Class\Constructor\Field\Method等几个类!

一、Class类、java中把所有共性特点的事物,描述为一个类,而 Class则是描述java中所有类的这么一个事物,所以他也是一个类。这个类的实例对象为java中各个类的字节码文件。获取Class实例对象的方法总结下来有三种:1、类名.class 2、对象名.getClass() 3、Class.forName("某个类的完整名称");


二、什么是反射、张孝祥老师引用曾经一位学员的答案是:把java类中的各种成份映射成相应的java类。

每一个java类中都有相应的构造成分,类似Constructor构造函数,Field成员变量(字段),Mehtod 方法等等。而这些构造成一个类的各种成分,本身也可以被描述为一种类。接下来就用到了Class类,该类封装了很多返回相应成份对象的方法,包括:getConstructor(),返回一个构造函数对象,getField()返回一个字段对象,getMethod()返回一个方法对象,而每一个构造函数,或者方法,或者成员变量的对象,其区别则体现在参数的不同,类似正常类的属性不同,如果参数相同,那么返回的就是同一个对象。当得到这些成份的对象时,原本正常情况通过对象调用函数或属性,现在反过来了,每一个方法或者成员变量或者构造函数的实例对象,都可以反过来作用于原本的类对象,从而实现相同的操作目的。

三、Constructor、构造函数类,该类的实例对象指向任意类的单独某一种构造函数,可以通过参数不同来区分。创建的方法:

Constructor constr=原类名.class.getConstructor(不同参数列表); (原类名)constr.newIstance(字节码参数列表); 返回一个原类对象。

四、Field、字段,也叫成员变量类,该类的对象指向任意类的某一个单独的属性,或者成员变量。可以通过原属性名区分字段对象,创建方法:

Field field=原类名.class.getField("原属性名"),field.get(原类对象),返回该对象的field属性值。

五、Method类,方法类,该类对象指向任意类的某一个方法,包括主函数、静态方法,和普通方法,可以通过原类方法名和参数来区分方法对象,创建该类对象的方法:

Method method=原类对象.getClass().getMehtod(原类的方法名",字节码参数列表]),如果是静态方法,则方法名处为空。

反射的作用,当不知道要被操作的数据类型时,该类名将会以参数形式传入,那么就可以通过反射,实现对该类的操作。


2015年9月11日,今天学习的内容有:数组与object类的关系、数组反射的应用、ArrayList和HashSet的比较及HashCode分析、框架的概念还有利用反射搭建框架

一、数组与Object的关系

1、具有相同维数和元素类型的数组,其.class类型相同,就是共用同一份字节码;

2、代表数组的Class实力对象,其.getSuperClass(),返回的父类是Object.class;(所有Class的父类是Object,所以所有Class的实例对象的getSuperClass()返回的都应该是Object.class);

3、基本数据类型的数组,只可以被看作是Object 对象,而不能被看作是Object[]数组,非基本数据类型的数组,其数组中存储的是对象,可以被看作是 Object数组;

4、集合中存储的是对象,如果用Arrays.asList()方法,可以将非基本数据类型的数组转化成包含该数组元素的集合,数组中存储的对象转化为集合的元素,而基本类型的数组,其整个数组只能是被当做一个对象,存储到集合当中;

二、数组反射的应用(数组是一个特殊的类,其反射的操作工具类Array可以对比java类中的各种成份对比理解和记忆,不过其方法都是静态的)

1、Array工具类用于对数组反射的操作。可以用来判定一个对象的.getClass().isArray ,即是不是数组类型的,如果是数组类型,则可以通过Array.get(obj,x)获取数组中指定的元素;

2、Array的静态set方法,可以用来对数组中指定索引的对象进行赋值操作!

3、Aryy的 newInstance()(Class<?> componentType, int length) 方法,可以获取指定组件类型和纬度的新数组!

三、ArrayList和HashSet的比较及HashCode分析

1、ArrayList底层是数组结构,可以存储任意类型的对象,且该集合的元素可以重复,元素本身是无序的;

2、HashSet底层是哈希表数据结构,可以存放任意类型的对象,集合内的元素不可以重复(默认是根据对象的地址换算的哈希值进行判断,而new出来的对象,系统会默认分配不同的地址,如果希望对属性值相同的两个对象作重复处理,则需要更改哈希值的计算方法);

3、HashCode的作用是用来给HashSet集合和HashMap集合添加元素时,判断元素所处的位置,从而存放元素。如果一个元素已经被添加到HashSet集合中,则不能再更改该元素参与哈希值计算的字段的值,否则,由于哈希值改变,再通过该元素的对象对其操作,比如移除操作,则不能操作成功,因为新的元素对象已经指向了另外一个哈希值所指向的地址,这样就造成了内存泄露(原对象没有响应的哈希值预期对应);

四、框架的概念以及反射在框架中的应用

1、个人理解框架的概念:事先被编辑好的一组代码,该代码中规定了这个项目要实现什么目的,待后期程序员将必要的对象提交给框架的入口时,实现框架的功能;

2、由于框架是事先编辑好的,那么就需要对外提供一个入口,将框架所需要的内容传入:

这里 可以做一份配置文件 Config.Properties,在配置文件中,设置一个Properties的集合元素,一个键值对:className=java.包名.类名,后面的开发人员只要将该配置文件的类名做修改,就会被框架调用;

框架内具体的实现过程如下代码:

//创建一个输入流关联配置文件

InputStream is=new FileInputStream("config.Properties");

//创建一个Properties对象

Properties pros=new Properties();

//利用Properties集合对象的加载方法,将流的内容加载到集合中

pros.load(ips);

//关闭流

ips.close();

//获取集合中指定键的值(也就是标的类名)

String className=pros.getProperty("className");

//用获取的类名得到其字节码,然后new对类的对象

Collection coll=(Collection)Class.forName("className").newInstance();

最后一部还可以改成这样!

Constructor cons=Class.forName("className").getConstructor();

由于搭建框架时,并不知道将会被传入的参数类名,所以此处无法确定构造函数中的参数类型及参数名称,所以如果反射被应用于框架,最好还是直接利用Class类的 无参 newInstance方法!

Collection coll=cons.newInstance();

0 0
原创粉丝点击