zoukankan      html  css  js  c++  java
  • 单例类与静态类的区别/单例类的实现代码/单例类的线程安全

    转自 https://www.2cto.com/kf/201311/260911.html 以及 http://www.cnblogs.com/xudong-bupt/p/3433643.html

    另一个更赞的链接

    http://blog.csdn.net/goodlixueyong/article/details/51935526

    单例模式与静态类(一个类,所有方法为静态方法)是另一个非常有趣的问题,在《Java中有关单例模式的面试问题》博文中露掉了,由于单例模式和静态类都具有良好的访问性,它们之间有许多相似之处,例如,两者可以直接使用而无须创建对象,都可提交唯一实例,在一个非常高的高度上看起来它们都为是用于同样的任务。由于它们具有较多的相似性,面试官常常会问一些类似为神马使用单例模式替换静态方法?你能使用静态类替换单例模式吗?Java中单例模式与静态的区别有那些?等这样的问题,为回答这些问题,记住他们单例模式和静态方法之间基本的区别是非常重要的,前者给你一个Object,后者仅仅提供静态方法,由于对像比方法具有较强的能力,可以指导你神马时候使用单例模式与静态方法。

    在本文中,我们会了解神马Java中的神马地方使用单例模式,神马时候使用静态类更好,顺便说下,JDK中有几个关于两者的例子,并且这例子非常聪明的,例如java.lang.Math是一个final类,并且其方法为静态方法,另一方面java.lang.Runtime是一个单例的类。对于那些不熟悉单例模式或静态类的人,静态类就是一个Java类,它仅包含静态方法,一个非常好静态类的例子就是java.lang.Math,它包括了许多为不同数据功能实现工具方法,例如sqrt(),而单例类,在整个应用生命周期内只有一个实例,例如java.lang.Runtime。

    神马时候在Java中使用静态类替换单例

    确实存在一些场景,静态类比单例更适合,这个场景中主要的一个例子就是java.lang.Math,它不是单例的,其所有方法都是静态方法,这里我给出几个场景,我觉得使用静态类比单例模式更适合。

    1)        如果你的单例不需要维护任何状态,仅仅提供全局访问的方法,这种情况考虑使用静态类,静态方法比单例更快,因为静态的绑定是在编译期就进行的。但是要记住,不建议在静态类中维护状态信息,特别是在并发环境中,若无适当的同步措施而修改多线程并发时,会导致坏的竞态条件。

    如果你需要将一些工具方法集中在一起时,你可以选择使用静态方法,但是别的东西,要求单例访问资源时,应该使用单例模式。

    Java中单例与静态的区别

    这是回答关于单例与静态的第二面试问题,如我早些提到过的,它们基本的区别一个表现类,一个表现方法,下面列几条它们之间的区别。

    1)        静态类比单例具有更好的性能,因为静态方法在编译期绑定。

    2)        再次,它们的区别是override的能力,因Java中的静态方法是不可以覆盖的,这就导致其木有太多的灵活性,另一面,你可通过继承的方式覆盖单例类中定义的方法。

    3)        静态类很难模拟,因此难于单例测试,单例更容易模拟,因为也比静态类易于编写单元测试,不论神马单例期望神马,你都可以传递模拟对象,例如构造方法或方法参数。

    4)        如果你的需求中需要维护状态信息,则单例比静态类更适合,因为后者在维护状态信息方面是非常可怕的,并导致狡滑的bug。

    5)        如果是一个非常重的对象,单例可以懒加载,但是静态类没有这样的优势,并且非常热切的加载。

    6)        许多依赖注入的框架对单例都有良好的管理,例如Spring,使用它们非常容易。

    两者之间的这些区别,有助于我们在面对一些场景时做出选择,下一节中了解神马时候选择单例而不是静态类。

    Java中,选择单例而不是静态类的优点

    单例与静态主要的优点是前者比后者更具有面向对象的能力,使用单例,可以通过继承和多态扩展基类,实现接口和更有能力提供不同的实现,如果我们讨论java.lang.Runtime,在Java中它是单例,调用getRuntime()方法,会基于不同的JVM返回不同的实现,但也保证了每个JVM中实有一个实例,如果java.lang.Runtime是一个静态类,不太可能因不同的JVM返回不同的实现。

    这就是Java中单例与静态类的区别,当你需要一个全OO能力的对象时,选择单例,如果仅仅是将一些静态方法预售,使用静态类。

  • 相关阅读:
    常用API及异常
    支付宝支付流程以及二次封装alipay包 支付模块后台接口的实现 订单接口实现
    课程页前台组件 课程模块的实现 表的设计及数据录入 课程详情页前台组件 课程详情页后台实现
    celery使用
    登录、注册、页头页面 手机号验证接口 发送短信接口 注册接口 多方式登录接口 手机号登录接口 发送短信接口频率限制 异常处理修订 接口缓存
    redis基础使用 python操作redis django-redis使用
    短信接口的使用(腾讯云)
    主页设计:页面头部组件 页面底部组件 轮播图组件 主页组件 主页后台: home模块创建 路由分发 Banner表的model设计 数据库迁移 注册模块
    前台vue环境配置 vue项目的创建 项目目录的重构 全局样式文件 配置文件 axios配置 cookies配置 element-ui配置 bootstrap和jquery的配置
    thinkphp6使用最新版本composer后多应用模式提示路由不存在
  • 原文地址:https://www.cnblogs.com/awomanofsin/p/7941707.html
Copyright © 2011-2022 走看看