JAVA-反射的应用

一、重要性:
在Java语言里之所以会有如此众多的开源技术支撑,很大的一部分来自于java最大的特征——反射机制,项目开发与设计不能灵活的使用反射机制,则并未接触到java的精髓。后期自定义开发框架
二、所有的技术实现的目标——重用性
三、“反”与“正”
当我们使用一个类的时候,一定先导入程序所在的包,而后根据类进行对象的时候,并且依靠对象调用类中的方法。“反”根据实例化对象反推出其类型。
四、范例:
正:import java.util.Date;//1、导入程序所在的包,类,知道对象的出处
Date date = new Date();//2、通过类产生实例化对象
System.out.println(date.getTime());//3、根据对象调用类中的方法
反:首先采用的就是Object类中所提供的方法
获取Class对象信息:public final Class<?>getClass();
java.long中找到 Object ——>getClass() 可以帮助使用者找到对象的根源
五、获得Class对象
反射之中所有的核心操作都是通过Class类对象展开的,可以说Class类是反射操作的实例化对象,可以采用三种方式完成:
1.【Object类支持】根据实例化对象获取Class对象 .getClass();
必须先产生指定类对象后才能使用(产生无用对象)
2.【JVM直接支持】采用“类.class”的形式实例化 Person.class
3.【Class类支持】在Class类中提供一个static方法:
public static Class<?>forName(String className) throws ClassNotFoundException
Class<?> class1 = Class.forName(“com.dmh512.demo.Person01”);
可以直接采用字符串的形式定义要使用的类型,并且不需要编写任何的import语句,连导包的这种耦合都没有了

观察java.long包里的Class类 since1.0 public final class Class extends
Object implements
Serializable(序列化),GenericDeclaration,Type,AnnotatedElement
从JDK1.5开始Class类在定义的时候可以使用泛型进行标记,希望可以避免向下转型。

七、意义
虽然获得了Class类的实例化对象,意义在于实际开发中使用代替了new。
1.【反射实例化对象】实例化对象操作的原因是因为Class类里面提供有一个对象的反射实例化方法:
1>1.9以前找到newInstance()——》Deprecated(要被替代了)因为默认的Class中的newInstance()只能调用无参构造,所以
2>1.9以后clazz.getDeclaredConstructor().newInstance();
通过newInstance()方法实例化Person01类对象
Class<?> class1 = Class.forName(“com.dmh512.demo.Person01”);
Object obj = class1.newInstance();//1.9以后废除 仍可用
//Object obj = class1.getDeclaredConstructor().newInstance();//1.9以后
if(obj instanceof Person01) {
System.out.println(obj);//输出对象 调用toString()方法
}
八、应用
现在通过反射实现的对象实例化处理,依然要调用类中的无参构造方法,等于“类 对象= new 类();”
反射与工厂设计模式
如果要想进行对象的实例化处理除了可以使用关键字new之外,还可以使用反射机制来完成。
【思考:】为什么要提供一个反射的实例化,与new相比怎么选择?
【工厂设计模式:】最大特点:客户端的一个程序类不直接牵扯到对象的实例化管理,只与接口发生关联,通过工厂类获取指定接口的实例化对象。最有效解决的是子类与客户端的耦合问题,但是解决的核心思想在于提供一个工厂类作为过渡端,当更多子类出现时则出现问题。
【传统工厂设计模式:】工厂类:要判断传入的参数是哪个子类 并且new
public static IMessageFac getInstance(String className) throws…{
//问题一:写了以下代码 不能满足其他子类 //解决方案 不适用关键字new
// if(“netmessage” .equalsIgnoreCase(className)) {
// return new NetMessageFac();
// }
// return null;
}
此种静态工厂设计模式,每次追加一个子类都需要额外修改代码进行判断 否则无法获取指定接口对象。
public static IMessageFac getInstance(String className) throws…{
//工厂不再需要判断
IMessageFac ins = null;
//问题二:如果同时要满足多个接口则又会出现代码重复
ins = (IMessageFac)Class.forName(className).newInstance();
return ins;
}

九、工厂扩展多接口(泛型)
此时的工厂设计模式将不再受限于指定的接口,可以为所有的接口提供实例化服务,达到可重用性
public static T getInstance(String className , Class clazz) throws…{
T ins = null;
ins = (T)Class.forName(className).newInstance();
return ins;
}
IMessageFac msg = null;
msg = Factory.getInstance(“com.dmh512.demo.CloudMessageFac”,IMessageFac.class);
msg.send();

	IServiceFac svc = null;
	svc = Factory.getInstance("com.dmh512.demo.HouseService",IServiceFac.class);
	svc.service();

十、反射与单例设计模式
单例设计模式的核心本质在于在类的内部的构造方法私有化,类内部产生实例化对象之后通过static方法获取实例化对象进行类中的结构调用。分为懒汉式、饿汉式。以下讨论懒汉式单例设计模式。

单例设计模式的特点是在整体的运行过程之中只允许产生一个实例化对象,当有了若干线程之后,当前程序将产生多个实例化对象,此时不再是单例设计模式。

【面试题】请编写单例设计模式
1》直接编写一个饿汉式的单例设计模式,并且实现构造方法私有化
2》在java中哪里使用到单例设计模式了?Runtime类、 Pattern 、Spring框架
3》懒汉式单例设计模式的问题?

无论你在学习上有任何问题,重庆蜗牛学院欢迎你前来咨询,联系QQ:296799112

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值