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高级-反射的三种实例化模式及与工厂,单例模式的的关系相关推荐

  1. Class java用法,java中Class的三种实例化

    1.调用Object类中的getClass()方法:import java.util.Date; public class ReflectTest3 { public static void main ...

  2. Java的三种代理模式完整源码分析

    Java的三种代理模式&完整源码分析 Java的三种代理模式&完整源码分析 参考资料: 博客园-Java的三种代理模式 简书-JDK动态代理-超详细源码分析 [博客园-WeakCach ...

  3. Java的三种代理模式【附源码分析】

    Java的三种代理模式&完整源码分析 代理模式分为两种,静态代理和动态代理,动态代理包括JDK动态代理和Cglib动态代理. 静态代理 静态代理在使用时,需要定义接口或者父类,被代理对象与代理 ...

  4. java .class 实例对象_Java产生Class类的三种实例化对象的方法

    Java产生Class类的三种实例化对象的方法 1.object.getClass 2.类名.class直接根据某个具体的类来取得Class实例化对象 3.Class.forName(String c ...

  5. Java的三种代理模式简述

    本文着重讲述三种代理模式在java代码中如何写出,为保证文章的针对性,暂且不讨论底层实现原理,具体的原理将在下一篇博文中讲述. 代理模式是什么 代理模式是一种设计模式,简单说即是在不改变源码的情况下, ...

  6. java 反射 找不到方法_Java获取反射的三种方法

    class Student { private int id; String name; protected boolean sex ; pub1ic f1oat score; } pub1ic cl ...

  7. 文件处理,文件的三种打开模式,绝对路劲和相对路径,with管理网文件上下文,文件的高级应用,文件的修改,登陆注册。...

    1.文件处理 什么是文件处理:修改存储的信息. 什么是文件:操作系统提供的虚拟概念,存储信息(用二进制存储信息) 操作核心是:读和写. 1.1操作文件的流程: 1.打开文件流程:1.文件路径" ...

  8. zmq java 消息阻塞_ZMQ的三种消息模式

    一. ZMQ是什么? 普通的socket是端对端(1:1)的关系,ZMQ是N:M的关系,socket的连接需要显式地建立连接,销毁连接,选择协议(TCP/UDP)和 错误处理,ZQM屏蔽了这些细节,像 ...

  9. IaaS, PaaS和SaaS是云计算的三种服务模式

    原文链接:https://zhidao.baidu.com/question/584394281.html IaaS, PaaS和SaaS是云计算的三种服务模式. SaaS:Software-as-a ...

  10. spark sql 本地调试_Spark精华问答|Spark的三种运行模式有何区别?

    戳蓝字"CSDN云计算"关注我们哦! Spark是一个针对超大数据集合的低延迟的集群分布式计算系统,比MapReducer快40倍左右,是hadoop的升级版本,Hadoop作为第 ...

最新文章

  1. PHP学习笔记-PHP与Web页面的交互2
  2. 如何查看表和索引的统计信息
  3. 小白入门PyTorch | 第一篇:什么是PyTorch?
  4. 重庆职高统考c语言,2021年重庆市中职毕业生参加高职分类考试招生文化素质测试 考试说明...
  5. 位运算和进制转换,反码补码
  6. jieba分词并做分析
  7. 目前服务器操作系统版本,目前服务器操作系统版本号
  8. 摩根大通:iPhone 13和新款iPhone SE将推动苹果业绩明年再破纪录
  9. 源数据怎么排查重复MySQL_面试官:在使用mysql数据库时,遇到重复数据怎么处理?...
  10. 父级div没高度不能自适应高度的原因——子级使用css float浮动
  11. Android内核开发 Linux C编程调用内核模块设备驱动
  12. 【筛法】第十万零二个素数
  13. POJ 2068 NIm (dp博弈,每个人都有特定的取最大值)
  14. 竞价推广和信息流推广是什么?区别在哪里?
  15. Elasticsearch构建全文搜索系统
  16. 【转载】MiniGUI输入法词库更新
  17. 第四篇 安装系统与多重引导
  18. 欧洲为何没有很牛掰的互联网公司
  19. python运营日报邮件自动化
  20. 工控机上安装服务器级虚拟机vmware ESXi6.7

热门文章

  1. 博科brocade光纤交换机alias-zone的划分--实操案例
  2. 排序算法——直接选择排序
  3. 对于NAS,IP SAN以及iSCSCI SAN存储的一些认识和理解
  4. SqlHelper和数据访问层
  5. 098 元类(metaclass)
  6. Dynamics 365 Online-Unified User Interface
  7. Ruby——关于require与require_relative
  8. 简单介绍.Net3.0 中跨线程访问控件
  9. 软件工程之系统建模篇【设计接口类模型】
  10. Coolite 换肤