反射机制简介
java之所以会有如此众多的开源技术支撑,很大一部分是来自于java最大特征----反射机制,如果不能灵活的使用反射机制进行项目的开发和设计,那么你并没有接触到java的精髓。所有的技术实现的目标只有一点:重用性
正:使用一个类的时候 导包 创建对象 调用方法
反:由实例化对象反推其类型 实现操作的方法:获取Class对象信息:public final Class<?> getClass();
getClass()可以帮助使用者找到对象的根源。
Class类对象的三种实例化模式
反射之中所有的核心操作都是通过Class对象展开的,可以说Class类是反射操作的根源所在,获取了Class类的实例就获取了类的全部操作权限。但是这个类如果要想获取它的实例化对象有三种方式
1、Object支持:Class clazz = 对象.getClass();
2、JVM直接支持:Class clazz = 类.class;
3、Class类支持:Class clazz = Class.forName("全类名");最灵活,全类名不存在classNotFound异常
上面三种形式全部都要掌握
反射实例化对象(代替关键字new)
上面得到的clazz意义不是很大(个人理解:clazz指向一个类的字节码)
JDK1.9之前:Object obj = clazz.newInstance();(内部默认使用无参构造创建一个对象)
JDK1.9之后:Object obj = clazz.getDeclaredConstructor().newInstance();(中间多出来的表示使用的是无参构造,说明1.9之后支持有参构造实例化对象了)
反射与工厂设计模式
为什么要提供一个反射的方式实例化呢?用new还是用反射呢?
工厂设计模式客户端程序类不直接牵扯到对象实例化管理,只与接口关联
传统的工厂弊端:1、一个接口有很多的子类,接口扩充子类时要修改工厂类的结构,增加分支语句判断实例化的子类 2、一个接口一个工厂,多个接口多个工厂,只能满足一个接口或抽象类获取实例化对象的需求
package cn.mldn.demo; interface IMessage{ public void send(); } class CloudMessage implements IMessage{ public void send() { System.out.println("【云消息】www.mldnjava.cn"); } } class NetMessage implements IMessage{ public void send() { System.out.println("【网络消息】www.mldn.cn"); } } class Factory{ 以后有了反射工厂,不需要再做改变了 private Factory() {} @SuppressWarnings("unchecked") public static <T>T getInstance(String className,Class<T> clazz){ 实现类名 接口名 T instance = null; try { instance = (T)Class.forName(className) .getDeclaredConstructor(null).newInstance(); }catch(Exception e) { e.printStackTrace(); } return instance; } } public class JavaReflectDemo { public static void main(String[] args) { IMessage msg = Factory.getInstance("cn.mldn.demo.NetMessage",IMessage.class); msg.send(); } }