java高级-反射的三种实例化模式及与工厂,单例模式的的关系
2019独角兽企业重金招聘Python工程师标准>>>
一、概述
所谓反射,就是根据实例化对象找到对象的根源。
范例:观察Class对象的使用
/*根据对象找到对象的根源**/ public class Demo {public static void main(String[] args) {Date date = new Date();System.out.println(date.getClass());} }
运行结果:
二、Class类对象三种实例化模式
反射之中所有的核心操作都是通过Class类对象展开的,可以说Class是反射操作的根源所在,要想获取他的实例化对象,可以采用三种方式来完成。
1.【Object类支持】Object类可以通过实例化对象获取Class
class Person{}public class MainDemo {public static void main(String[] args) {Person person = new Person();Class<? extends Person> cls = person.getClass();System.out.println(cls.getName());} }
运行结果:
2.【JVM直接支持】利用“类.Class”的形式来实例化
class Person{}public class MainDemo {public static void main(String[] args) {Class<?> cls = Person.class;System.out.println(cls.getName());} }
运行结果:
3.【Class类支持】在Class类中提供了一个static方法
- 方法:public static Class<?> forName(String className) throws ClassNotFoundException;
package com.cz.test;public class Person { }
public class MainDemo {public static void main(String[] args) {try {Class<?> cls = Class.forName("com.cz.test.Person");System.out.println(cls.getName());} catch (ClassNotFoundException e) {e.printStackTrace();}} }
运行结果:
这种模式不需要导入包(import语句),直接通过字符串的类名来操作,如果该类不存在,则会抛出“ClassNotFoundException”异常。
三、相关经典案例
1.反射实例化对象
范例:通过newInstance()来实例化对象
package com.cz.test;public class Person {public Person(){System.out.println("这是无参构造方法!!");}public String toString(){return "一个努力的人!!";} }
public class MainDemo {public static void main(String[] args) {try {Class<?> cls = Class.forName("com.cz.test.Person");try {Object obj = cls.newInstance();System.out.println(obj);} catch (Exception e) {e.printStackTrace();}} catch (ClassNotFoundException e) {e.printStackTrace();}} }
运行结果:
但是在JDK1.9之后就被不推荐使用了,主要是因为默认的Class类中的newInstance()方法只能够调用无参构造方法,所以很多开发者认为其描述不准确,所以将它变换了形式。
范例:通过getDeclaredConstructor().newInstance()来实现
public class MainDemo {public static void main(String[] args) {try {Class<?> cls = Class.forName("com.cz.test.Person");try {Object obj = cls.getDeclaredConstructor().newInstance();System.out.println(obj);} catch (Exception e) {e.printStackTrace();}} catch (ClassNotFoundException e) {e.printStackTrace();}} }
运行结果:
2.反射与工厂设计模式
工厂设计模式不直接牵扯到对象的实例化管理,只与接口发生关联,通过工厂类获取指定接口的实例化。
范例:传统工厂设计模式
public class Test {public static void main(String[] args) {IMessage iMessage = Factory.getInstance("NetMessage");iMessage.send();} } interface IMessage{void send(); }class NetMessage implements IMessage{@Overridepublic void send() {System.out.println("网络消息发送");} } class Factory{private Factory(){ //无参构造器,私有化}public static IMessage getInstance(String classname){ //实例化方法if("NetMessage".equals(classname)){return new NetMessage();}else{return null;}} }
运行结果:
以上静态工厂模式存在弊端,每当增加一个子类,工厂类中就必须修改实例方法。所以要解决此问题,最好不使用关键字new.利用反射机制来实现。
范例:解决添加子类后必须修改工厂类的弊端
public class Test {public static void main(String[] args) {IMessage iMessage = Factory.getInstance("NetMessage");iMessage.send();} } interface IMessage{void send(); }class NetMessage implements IMessage{@Overridepublic void send() {System.out.println("网络消息发送");} } class Factory{private Factory(){}public static IMessage getInstance(String classname){IMessage iMessage = null;try {iMessage = (IMessage)Class.forName(classname).getDeclaredConstructor().newInstance();} catch (Exception e) {e.printStackTrace();}return iMessage;} }
运行结果:
但是以上程序任然没有达到最好的效果,如果用户想增加接口,则必须增加工厂类中的实例化方法,任然要求修改factory类,所以,只能用泛型的方式来解决此问题。
范例:使用泛型来解决增加接口的问题
public class Test {public static void main(String[] args) {IMessage iMessage = Factory.getInstance("NetMessage",NetMessage.class);iMessage.send();IService iService = Factory.getInstance("HouseService",HouseService.class);iService.service();} } interface IMessage{void send(); }class NetMessage implements IMessage{@Overridepublic void send() {System.out.println("网络消息发送");} }interface IService{void service(); }class HouseService implements IService{@Overridepublic void service() {System.out.println("提供住房服务");} } class Factory{private Factory(){}public static <T> T getInstance(String classname,Class<T> clazz){T intance = null;try {intance = (T)Class.forName(classname).getDeclaredConstructor().newInstance();} catch (Exception e) {e.printStackTrace();}return intance;} }
运行结果:
此时的工厂设计模式将不会受限于指定的接口。
3.反射与单例设计模式
/*** 单例模式(懒汉式)*/ public class Demo1 {public static void main(String[] args) {for(int i = 0; i < 3 ; i++){new Thread(()->{Singleton.getSingleton().print();},"线程"+i).start();}}} class Singleton{public static volatile Singleton singleton = null;private Singleton(){ //私有化构造方法System.out.println(Thread.currentThread().getName()+"实例化");}public static Singleton getSingleton(){if(singleton == null){synchronized(Singleton.class){if(singleton == null) {singleton = new Singleton();}}}return singleton;}public void print(){System.out.println("666");} }
注:初学者,写的不好请见谅,如有相关问题记得私信我
转载于:https://my.oschina.net/chenzhou/blog/2208498
java高级-反射的三种实例化模式及与工厂,单例模式的的关系相关推荐
- Class java用法,java中Class的三种实例化
1.调用Object类中的getClass()方法:import java.util.Date; public class ReflectTest3 { public static void main ...
- Java的三种代理模式完整源码分析
Java的三种代理模式&完整源码分析 Java的三种代理模式&完整源码分析 参考资料: 博客园-Java的三种代理模式 简书-JDK动态代理-超详细源码分析 [博客园-WeakCach ...
- Java的三种代理模式【附源码分析】
Java的三种代理模式&完整源码分析 代理模式分为两种,静态代理和动态代理,动态代理包括JDK动态代理和Cglib动态代理. 静态代理 静态代理在使用时,需要定义接口或者父类,被代理对象与代理 ...
- java .class 实例对象_Java产生Class类的三种实例化对象的方法
Java产生Class类的三种实例化对象的方法 1.object.getClass 2.类名.class直接根据某个具体的类来取得Class实例化对象 3.Class.forName(String c ...
- Java的三种代理模式简述
本文着重讲述三种代理模式在java代码中如何写出,为保证文章的针对性,暂且不讨论底层实现原理,具体的原理将在下一篇博文中讲述. 代理模式是什么 代理模式是一种设计模式,简单说即是在不改变源码的情况下, ...
- java 反射 找不到方法_Java获取反射的三种方法
class Student { private int id; String name; protected boolean sex ; pub1ic f1oat score; } pub1ic cl ...
- 文件处理,文件的三种打开模式,绝对路劲和相对路径,with管理网文件上下文,文件的高级应用,文件的修改,登陆注册。...
1.文件处理 什么是文件处理:修改存储的信息. 什么是文件:操作系统提供的虚拟概念,存储信息(用二进制存储信息) 操作核心是:读和写. 1.1操作文件的流程: 1.打开文件流程:1.文件路径" ...
- zmq java 消息阻塞_ZMQ的三种消息模式
一. ZMQ是什么? 普通的socket是端对端(1:1)的关系,ZMQ是N:M的关系,socket的连接需要显式地建立连接,销毁连接,选择协议(TCP/UDP)和 错误处理,ZQM屏蔽了这些细节,像 ...
- IaaS, PaaS和SaaS是云计算的三种服务模式
原文链接:https://zhidao.baidu.com/question/584394281.html IaaS, PaaS和SaaS是云计算的三种服务模式. SaaS:Software-as-a ...
- spark sql 本地调试_Spark精华问答|Spark的三种运行模式有何区别?
戳蓝字"CSDN云计算"关注我们哦! Spark是一个针对超大数据集合的低延迟的集群分布式计算系统,比MapReducer快40倍左右,是hadoop的升级版本,Hadoop作为第 ...
最新文章
- PHP学习笔记-PHP与Web页面的交互2
- 如何查看表和索引的统计信息
- 小白入门PyTorch | 第一篇:什么是PyTorch?
- 重庆职高统考c语言,2021年重庆市中职毕业生参加高职分类考试招生文化素质测试 考试说明...
- 位运算和进制转换,反码补码
- jieba分词并做分析
- 目前服务器操作系统版本,目前服务器操作系统版本号
- 摩根大通:iPhone 13和新款iPhone SE将推动苹果业绩明年再破纪录
- 源数据怎么排查重复MySQL_面试官:在使用mysql数据库时,遇到重复数据怎么处理?...
- 父级div没高度不能自适应高度的原因——子级使用css float浮动
- Android内核开发 Linux C编程调用内核模块设备驱动
- 【筛法】第十万零二个素数
- POJ 2068 NIm (dp博弈,每个人都有特定的取最大值)
- 竞价推广和信息流推广是什么?区别在哪里?
- Elasticsearch构建全文搜索系统
- 【转载】MiniGUI输入法词库更新
- 第四篇 安装系统与多重引导
- 欧洲为何没有很牛掰的互联网公司
- python运营日报邮件自动化
- 工控机上安装服务器级虚拟机vmware ESXi6.7