1OOP进阶之一动态与反射文档格式.docx

上传人:b****3 文档编号:6901942 上传时间:2023-05-07 格式:DOCX 页数:22 大小:242.71KB
下载 相关 举报
1OOP进阶之一动态与反射文档格式.docx_第1页
第1页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第2页
第2页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第3页
第3页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第4页
第4页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第5页
第5页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第6页
第6页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第7页
第7页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第8页
第8页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第9页
第9页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第10页
第10页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第11页
第11页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第12页
第12页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第13页
第13页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第14页
第14页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第15页
第15页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第16页
第16页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第17页
第17页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第18页
第18页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第19页
第19页 / 共22页
1OOP进阶之一动态与反射文档格式.docx_第20页
第20页 / 共22页
亲,该文档总共22页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

1OOP进阶之一动态与反射文档格式.docx

《1OOP进阶之一动态与反射文档格式.docx》由会员分享,可在线阅读,更多相关《1OOP进阶之一动态与反射文档格式.docx(22页珍藏版)》请在冰点文库上搜索。

1OOP进阶之一动态与反射文档格式.docx

4.IOC模式2构造注入(代理对象):

10

4.AOP代理分析:

11

5.IOC结构分析:

13

6.Struts/Hibernate/Spring实现原理分析14

总结和任务:

15

一切皆为对象!

 

1.java的类装载体系与动态载入

1.类装载基础

ClassLoader加载体系中的核心API:

Class,ClassLoader,Object

动态装载的关节点:

Class.forName(“要装载的类的名字“);

1)检查当前内存中是否有该类,若有直接返回,若无,请求父类的ClassLoader加载,如无父类,则从从bootstapclassloader加载,即JDK基本类库;

通过这种委托装载机保,保证每个类只被装载一次!

在编译或运行时,可能过-verbose标志查看装载的类。

2)具体分析java.lang.ClassLoader中的相关方法,这是一个抽像类---你可以重写它,从任意地方以字节流的行式加载需要的类到当前jvm中。

装载后执行顺序:

1.静态块执行;

--如不写main方法,执行程序?

2.创建对象后,属性赋值,非静态块执行.

3.初始化的过程:

父类-类static块属性-构造器?

常见的是程序中抛出java/lang/ClassNotFoundException:

...

则肯定是通过Class.forName(“ClassName”)时没有找到类。

如果把源码比做剧本,对象就是演员,JVM就是舞台。

静态编译:

在编译时确定类型,绑定对象,即通过。

动态编译:

运行时(RunningTime)确定类型,绑定对象。

动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性,即Class.forName(“ClassName”)应用。

为了继承以下示例,我们编写了简单的继承代码:

packageref;

/**

*机动车接口定义

*@author:

蓝杰

*/

publicinterfaceIVehicle{

publicvoidstartMe();

//启动

publicintforward(intdins);

//前进;

//有多少油

publicintgetEnergy();

}

//机动车实现类:

宝马车

publicclassBMWimplementsIVehicle{

publicstaticfinalStringcompany="

宝马公司"

;

publicintenergy;

//能量

publicBMW(){

this.energy=10;

}

publicBMW(intenergy){

this.energy=energy;

//启动

publicvoidstartMe(){

System.out.println("

BMW启动...."

);

//前进;

publicintforward(intdins){

energy-=dins/100;

BMW前进"

+dins);

returnenergy;

//有多少能量

publicintgetEnergy(){

returnthis.energy;

静态编译/静态绑定:

//静态绑定:

IVehiclevehicle=newBMW();

vehicle.forward(100);

动态编译/绑定/运行时多态:

//1.载入类对象

Classc=Class.forName("

ref.BMW"

//2.调用默认无参构造器生成对象

Objectobject=c.newInstance();

//3.强制转型

IVehicleve=(IVehicle)object;

ve.forward(500);

优点?

Reflection是Java被视为动态(或准动态)语言的一个关键性质。

这个机制允许程序在运行时通过ReflectionAPIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public,static等等)、superclass(例如Object)、实现的interfaces,也包括fields和methods的所有信息,并可于运行时改变fields内容或调用Constructor,methods。

BMWb=newBMW();

//判断对象所属的类型

if(binstanceofBMW){

System.out.println("

是BMW类型!

"

}

if(binstanceofIVehicle){

是IVehicle类型!

Classc=b.getClass();

StringclassName=c.getName();

System.out.println("

类的名字是:

"

+className);

//得到类中的方法对象数组

java.lang.reflect.Method[]methods=c.getMethods();

//得到类定义的构造器对象数组

java.lang.reflect.Constructor[]cons=c.getConstructors();

//得到类定义的属性对象数组

java.lang.reflect.Field[]fields=c.getFields();

//得到类的直接父类类对象

ClasssuperClass=c.getSuperclass();

//得到类所有实现的接口类对象数组

Class[]interfaces=c.getInterfaces();

privatestaticvoidprintFiledInfo(java.lang.reflect.Field[]fields){

共有属性:

+fields.length);

for(java.lang.reflect.Fieldf:

fields){

StringfName=f.getName();

属性名字是:

+fName);

ClassfType=f.getType();

属性类型是:

+fType);

//得到属性的访问限定符

intmType=f.getModifiers();

//判断是何种限定符

if(java.lang.reflect.Modifier.isPublic(mType))

public"

if(java.lang.reflect.Modifier.isAbstract(mType))

abstract"

if(java.lang.reflect.Modifier.isFinal(mType))

final"

//输出所有接口名字

privatestaticvoidprintInterface(Class[]interfaces){

for(Classc:

interfaces){

接口名:

+c.getName());

Class[]cs=c.getInterfaces();

printInterface(cs);

}

//输出所有父类名字

privatestaticvoidprintSuper(ClasssuperClass){

+superClass.getName());

Classss=superClass.getSuperclass();

if(null!

=ss){

printSuper(ss);

}

//打印方法信息

privatestaticvoidprintMethodInfo(java.lang.reflect.Method[]methods){

for(java.lang.reflect.Methodm:

methods){

intt=m.getModifiers();

限定符是:

+t);

Stringname=m.getName();

方法名是:

+name);

ClassreturnType=m.getReturnType();

返回值类型是:

+returnType.getName());

//参数类型组....

Classps[]=m.getParameterTypes();

//异常类型组...

Classes[]=m.getExceptionTypes();

//打印构造器信息

privatestaticvoidprintConstructorInfo(java.lang.reflect.Constructor[]cons){

for(java.lang.reflect.Constructorcon:

cons){

//构造器限定符

intm=con.getModifiers();

//得到参数类型表...

Class[]ptype=con.getParameterTypes();

BMWbm=createObj("

//根据类名字,用无参构造器创建类的对象

publicstaticBMWcreateObj(StringclassName){

try{

Objectobj=Class.forName(className).newInstance();

if(objinstanceofBMW){

BMWbm=(BMW)obj;

returnbm;

}catch(InstantiationExceptione){

System.out.println(e);

}catch(IllegalAccessExceptione){

}catch(ClassNotFoundExceptione){

returnnull;

3.2调用指定的构造器创建对象

通过前面对象的解析,我们可以得到类的构造器对象和其参数表,如下代码,即可调用指定的构造器创建对象:

/**

*调用有参数的构造器创建对象

*@paramconstructor:

构造器对象

*@paramarguments:

参数表

*@return:

创建好的对象

publicstaticObjectcreateObject(Constructorconstructor,

Object[]arguments){

Objectobject=null;

try{

object=constructor.newInstance(arguments);

Object:

+object.toString());

returnobject;

System.out.println(e);

}catch(IllegalAccessExceptione){

}catch(IllegalArgumentExceptione){

}catch(InvocationTargetExceptione){

returnobject;

调用方法前,必须己知方法的名字,方法参数类型,如下示:

*调用对象的方法

*@parambmw:

要调用的对象

*@paramdestName:

要调用的方法名字

*@paramparaType:

方法参数类型列表

publicstaticvoidinvokeTest(BMWbmw,StringdestName,Class...paraType){

//得到对象所在的类:

ClassdestClass=BMW.class;

//查询到要调用的方法对象

java.lang.reflect.MethoddestM=destClass.getMethod(destName,paraType);

if(null!

=destM){

//调用方法,传入参数

Objectobj=destM.invoke(bmw,300);

System.out.println(destM+"

调用结果是"

+obj);

}catch(Exceptionef){

ef.printStackTrace();

Class

Description

Array

提供动态(dynamically)创建、访问数组的类方法.

表述(Represents),反射(reflects)类或接口.

Constructor

提供访问或提取类的构造器的方法和动态创建类的方法.

Field

提供动态访问、设置类或接口域数据的方法.

Method

提供动态访问、调用类或接口的方法.

Modifier

提供静态方法提取类及其成员的modifiers信息.

Object

提供了一个getClass取得这个对象的类对象(classObject)

//BMW是实现了IVehicle接口的类

IVehiclev=newBMW();

//根据接口中定义的方法调用...

v.startMe();

图:

优点:

Client不必知道其使用对象的具体所属类。

一个对象可以很容易地被(实现了相同接口的)的另一个对象所替换。

对象间的连接不必硬绑定(hardwire)到一个具体类的对象上,因此增加了灵活性。

松散藕合(loosenscoupling);

增加了重用的可能性。

工厂类一般为单态模式:

classVehicleFactory{

//最简单的工厂方法

publicIVehiclecreateIVehicle(StringclassName){

IVehiclev=(IVehicle)Class.forName(className).newInstance();

returnv;

returnv;

IOC:

InversionofControlDI:

DependencyInjection

publicinterfaceDriver{

publicvoidsetVehicle(IVehiclevehicle);

publicvoidgo();

//userCode:

publicvoidtest(IVehiclev,Driverd){

d.setVehicle(v);

d.go();

如图示例:

基实是包装器的设计思路:

classBigBM()implementsIVehicle{

privateIVehiclev;

publicBigBM(IVehiclev){

this.v=v;

超级宝马启动!

!

publicvoidtest(IVehiclev){

BigBMb=newBigBM(v);

b.startMe();

如下图示:

考虑javaIOAPI中过滤器流的设计,就是这种实现方式。

以上都无法解决的问题:

源码级藕合!

4.AOP代理实现:

同现实中“代理”一词的意思相同:

比如我要去买保险,要调用的关键方法只有一个:

传入人民币,拿到保单;

但这其中还有很多跟我关注的核心方法无关的动作执行,如填写资料表,审核资料,提交证明...与是,我通过一个保险代理人来买保险---通过代理对象执行我需要的调用----我就可专注于自己想要的东东了。

调用一个对象的方法时,可通这调用这个对象的“代理对象“执行,如果某些方法要日志记录,事务管理,审计…,就只需修改代理类中的方法,而不必修改对象“原类”中的代码。

要实现这一功能,必须先编写一个通用的代理类,如下:

importjava.lang.reflect.InvocationTargetException;

importjava.lang.reflect.Method;

*通用的代理类实现

publicclassDebugVehicleProxyimplementsjava.lang.reflect.InvocationHandler{

//被代理的对象

privateObjectobj;

//得到代理对象

publicstaticObjectgetProxy(Objectobj){

returnjava.lang.reflect.Proxy.newProxyInstance(obj.getClass()

.getClassLoader(),obj.getClass().getInterfaces(),

newDebugVehicleProxy(obj));

privateDebugVehicleProxy(Objectobj){

this.obj=obj;

*实现InvocationHandler中的方法

*被代理类调用时,实际上是通过这个方法调用的

*@paramproxy:

被调用方法的对象

*@paramm:

要调用的方法对象

*@paramargs:

调用方法的参数列表

publicObjectinvoke(Objectproxy,Methodm,Object[]args)throwsThrowable{

Objectresult;

debugadvicebegin:

+m.getName());

result=m.invoke(obj,args);

//调用实际对象的方法

throwe.getTargetException();

}catch(Exceptione){

thrownewRuntimeException("

invocation:

+e.getMessage());

}finally{

debugadvicefinash:

returnresult;

测试通过代理对象调用对象的方法:

publicclassDriver{

publicstaticvoidmain(Stringargs[]){

IVehiclesrcv=newBMW();

//代理前执行:

srcv.forward(100);

//通过代理对象执行

IVehiclev=(IVehicle)DebugVehicleProxy.getProxy(s

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2