1最近在重构项目中的老模块,打算引入spring boot对原有项目自己封装的依赖注入模块进行替换。项目中存在大量的工具类,大都是使用static方法编写的,比如时间工具类用于格式化日期,编码工具类用于编码解码。研究了下是否有必要对这些常量方法的类进行单例重构。

首先要说明的是,两种方式都是可以实现功能的,只在一些特殊的场景会有些区别。除非比较感兴趣,一般是没必要太深究

区别和特点:

单例:有实例,有状态

静态方法:无实例,无状态,纯函数

静态方法实现方式的优点是突出了一个简单粗暴,不实例对象,并且由于静态方法是在编译期静态绑定的,性能会有一点提升。对于大部分业务无关的工具类,确实比较适合这种场景。

缺点也很明显,由于不实例化对象,也就不遵守面向对象的设计。什么高内聚低耦合,单元测试,实现替换,AOP代理等等这些面向对象的优势,就都没有了,相较与面向对象会更加难以应对变更。

想用AOP的话,还是使用单例吧

静态在构造方法里会有this引用溢出问题 ,多多注意

2.是一个经常被时时提出来的问题,很多时候我们以为理解了、懂了,但深究一下,我们却发现并不懂。

方法是我们每天都在写得,很多程序员大多都使用实例化方法,而很少使用静态方法,问原因也说不出来所以然,或者简单的回答两者定义的区别,静态方法不需要new就可以使用 实例化方法需要new了以后才可以使用。。。。我们真的理解了吗?

从实际项目开发说起,这里有开发项目的三种方式:

开发项目中把BLL和DAL分开,在BLL调用DAL的代码。

一、在DAL中使用静态方法,不创建实例直接调用(大概有很多人都使用这种方式开发 )

class DAL
{
public static string GetUserName(...);
}
在BLL中调用:
DAL.GetUserName();

二、在DAL中使用实例方法,采用静态成员模式(或Singleton)通过实例来调用:
class DAL
{
public static readonly DAL dal = new DAL();
public string GetUserName(...);
}
在BLL中调用:
DAL.dal.GetUserName();

三、在DAL中使用实例方法,每次调用之前先创建DAL对象的实例:
class DAL
{
public string GetUserName(...);
}
在BLL中调用:
DAL dal = new DAL();
dal.GetUserName();

---------------------------------------------------------------

开发方式一:我以为在一些情况下(比如 调用多个数据库、GetUserName(...)内部处理操作部分)会出现线程安全的嫌疑。这种开发方式不用New出对象,所以很普遍。

开发方式二:应该多是应用在cs模式下,DAL在整个项目只会有一个对象存在,如果出现在B/S 我想不能兼容多种问题情况。而且也有线程安全的问题。

开发方式三:应该是普遍使用的,能够兼容各种问题,也不会有线程不安全的嫌疑出现。

特别说明一下:在MS的pet3.0以前的版本 都采用了方式二,而到pet3.0和以后的版本 都采用了方式三,而且特别在开发说明文档中明确的解释了一下。我想应该是从兼容性上考虑的,从性能上方式二并不比方式三真正的高多少。

-------------------------------------------------------------------------

我特意以“你怎么理解并使用静态方法和实例化方法的?”这样的问题询问了多位程序员,他们开发的语言也不尽相同(c 、c++、java、c#)

以下是他们的回答:

海龙说:

公用的方法,而且是一些零散的 一般用静态方法

张伟说:
几乎没有区别,如果不需要实例化,就用静态方法;如果为了稳妥,就用实例方法,这样才可调用其他实例方法和变量 。

萧远山说:
静态方法比较少用,因为他在一启动就实例化了,比较占资源,当然,,配合单例模式还是比较好用的
比较多的用在数据连接上,我避免使用的原则就是减少资源消耗。

张新波说:
静态方法意味着我在调用前不需要进行对其所属的类进行new操作,我主要会在工具类里面用到静态方法。

向详说:
静态就是类的,实例就是对象的。
静态方法和实例方法的区别之处还有一个地方:静态方法不需要依赖类当中的属性,能在这个方法中封闭的完成一个功能。实例方法更多的会使用到类当中的属性。

winson_张林说:
最大的区别在于内存。
静态方法在程序开始时生成内存,实例方法在程序运行中生成内存,
所以静态方法可以直接调用,实例方法要先成生实例,通过实例调用方法,静态速度很快,但是多了会占内存。
任何语言都是对内存和磁盘的操作,至于是否面向对象,只是软件层的问题,底层都是一样的,只是实现方法不同。
静态内存是连续的,因为是在程序开始时就生成了,而实例申请的是离散的空间,所以当然没有静态方法快,
而且静态内存是有限制的,太多了程序会启动不了。

showlover说:
静态方法与实例方法各有自己的用处...

是定义成静态方法,还是定义成实例方法,还要看具体情况,比如方法本身与类型没有太大的关系,可以定义成静态方法..

用实例方法,当然需要你先创建实例,才能调用实例方法,而静态方法则不需要..

从性能上说,静态方法效率要稍微高一些,但是它会常驻内存...
一些情况下使用静态方法是有好处的,因为对于静态方法无论你有多少个实例,
内存中要维护的一份拷贝。同时,某些方法,确实使用静态是比较恰当的..

Q.yuhen说:
这个问题牵扯到的东西比较多,诸如设计模式等等。简单点说,静态方法用来执行无状态的一个完整操作,实例方法则相反,它通常是一个完整逻辑的一部分,并且需要维护一定的状态值。
如果用内存和效率来区分使用Static Method、Instance Method 就回到过去结构化编程了。使用那种方法的根本出发点还是围绕面向对象来进行的。

陈亮说:

静态方法和全局函数差不多的,实例方法是一个类里面的方法。

总结:大家对这个问题都有一个共识:那就是实例化方法更多被使用和稳妥,静态方法少使用。

有时候我们对静态方法和实例化方法会有一些误解。

1、大家都以为“ 静态方法常驻内存,实例方法不是,所以静态方法效率高但占内存。

事实上,他们都是一样的,在加载时机和占用内存上,静态方法和实例方法是一样的,在类型第一次被使用时加载。调用的速度基本上没有差别。

2、大家都以为“ 静态方法在堆上分配内存,实例方法在堆栈上

事实上所有的方法都不可能在堆或者堆栈上分配内存,方法作为代码是被加载到特殊的代码内存区域,这个内存区域是不可写的。

方法占不占用更多内存,和它是不是static没什么关系。   
  因为字段是用来存储每个实例对象的信息的,所以字段会占有内存,并且因为每个实例对象的状态都不一致(至少不能认为它们是一致的),所以每个实例对象的所以字段都会在内存中有一分拷贝,也因为这样你才能用它们来区分你现在操作的是哪个对象。   
  但方法不一样,不论有多少个实例对象,它的方法的代码都是一样的,所以只要有一份代码就够了。因此无论是static还是non-static的方法,都只存在一份代码,也就是只占用一份内存空间。   
  同样的代码,为什么运行起来表现却不一样?这就依赖于方法所用的数据了。主要有两种数据来源,一种就是通过方法的参数传进来,另一种就是使用class的成员变量的值……

3、大家都以为“实例方法需要先创建实例才可以调用,比较麻烦,静态方法不用,比较简单

事实上如果一个方法与他所在类的实例对象无关,那么它就应该是静态的,而不应该把它写成实例方法。所以所有的实例方法都与实例有关,既然与实例有关,那么创建实例就是必然的步骤,没有麻烦简单一说。

当然你完全可以把所有的实例方法都写成静态的,将实例作为参数传入即可,一般情况下可能不会出什么问题。

从面向对象的角度上来说,在抉择使用实例化方法或静态方法时,应该根据是否该方法和实例化对象具有逻辑上的相关性,如果是就应该使用实例化对象  反之使用静态方法。这只是从面向对象角度上来说的。

如果从线程安全、性能、兼容性上来看  也是选用实例化方法为宜。

我们为什么要把方法区分为:静态方法和实例化方法 ?

如果我们继续深入研究的话,就要脱离技术谈理论了。早期的结构化编程,几乎所有的方法都是“静态方法”,引入实例化方法概念是面向对象概念出现以后的事情了,区分静态方法和实例化方法不能单单从性能上去理解,创建c++,java,c#这样面向对象语言的大师引入实例化方法一定不是要解决什么性能、内存的问题,而是为了让开发更加模式化、面向对象化。这样说的话,静态方法和实例化方式的区分是为了解决模式的问题。

拿别人一个例子说事:

比如说“人”这个类,每个人都有姓名、年龄、性别、身高等,这些属性就应该是非静态的,因为每个人都的这些属性都不相同;但人在生物学上属于哪个门哪个纲哪个目等,这个属性是属于整个人类,所以就应该是静态的——它不依赖与某个特定的人,不会有某个人是“脊椎动物门哺乳动物纲灵长目”而某个人却是“偶蹄目”的。

java使用单例与使用static方法的对于和个人理解相关推荐

  1. java实现单例的5种方法,快收藏

    1.饿汉式 饿汉式就是类加载后就创建好了单例,直接拿就行,但该方法容易产生垃圾 public class Singleton1 {//构造器私有化 防止外部实例private Singleton1() ...

  2. java 内部类 单例_确保对象的唯一性——单例模式 (四):一种更好的单例实现方法(静态内部类)...

    3.5 一种更好的单例实现方法 饿汉式单例类不能实现延迟加载,不管将来用不用始终占据内存:懒汉式单例类线程安全控制烦琐,而且性能受影响.可见,无论是饿汉式单例还是懒汉式单例都存在这样那样的问题,有没有 ...

  3. java设计模式 单例_java设计模式一(单例模式singleton)

    1 概述 如果要保证系统里一个类最多只能存在一个实例时,我们就需要单例模式.这种情况在我们应用中经常碰到,例如缓存池.数据库连接池.线程池.一些应用服务实例等.在多线程环境中为了保证实例的唯一性其实并 ...

  4. java test20006_Java单例7种测试实践

    单例:一个进程中只能存在唯一一个对象. 1.饿汉模式. 主动型太粗暴./** * @author :jiaolian * @date :Created in 2021-01-10 21:25 * @d ...

  5. java的单例设计模式

    java的单例设计模式包括:饿汉设计模式和懒汉设计模式: 步骤: 1.创建一个对象把他设置为私有的成员变量,保证唯一 2.私有构造方法,防止new一个对象. 3.定义一个公开的静态方法,返回第一步创建 ...

  6. cocos2d-x中为什么要用sharedXX()函数创建单例类的static对象

    如果在需要用到单例类对象时直接使用static成员对象,那么由于编译器对于不同的编译单元的编译顺序的不确定性,有可能在用到该static对象的时候该对象还没有初始化,而用函数sharedXX()创建单 ...

  7. java static是单例_JAVA基础-static关键字及单例设计模式

    static关键字 基本概念使用static关键字修饰成员变量表示静态的含义, 此时成员变量由对象层级提升为类层级, 也就是整个类只有一份并被所有对象共享. 该成员变量随着类的加载准备就绪, 与是否创 ...

  8. filter java 是单例的吗_JAVA 设计模式之 单例模式详解

    单例模式:(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.单例模式是创建型模式.单例模式在现实生活中应用也非常广泛. 在 J2EE 标准中,S ...

  9. java httpclient单例_java-8 – CloseableHttpClient.execute每隔几周就会冻结一次,尽管超时...

    我们有一个groovy单例,使用PoolingHttpClientConnectionManager(httpclient:4.3.6),池大小为200,以处理与搜索服务非常高的并发连接并处理xml响 ...

最新文章

  1. 从Date类型转为中文字符串
  2. AWS 发布了新的负载均衡器 ALB
  3. 【关于重载OnBackPressed无效的解决方案】
  4. Maatkit工具使用lt;一gt;之mysql主从数据校验工具
  5. Linux查看文件大小的几种方法
  6. android序列化异常,关于序列化:错误:Android中的序列化和反序列化
  7. C#跳转语句 迭代法 穷举法
  8. 几种搜索引擎算法的研究
  9. [CISCN2018]crackme-java
  10. QNX设置开机启动命令来修改IP地址
  11. osg第三方插件的编译方法(以jpeg插件来讲解)
  12. SQL Server T-SQL编程:数据库用户与安全设置
  13. 实现深拷贝的几种方法
  14. 【POJ - 1664】放苹果 (递归经典题 或 dp 或 母函数)
  15. OpenCV3与深度学习实例-使用OpenPose进行人体姿态估算
  16. axios 注册拦截器 cdn引用_CDN加速原理
  17. STL源码分析-rotate
  18. 我的世界服务器物品图标闪,我的世界用资源包修改闪烁标的方法分享
  19. 文档控件正在将数据上传到服务器,关于CellWeb插件中文件打开、上传、以及导入数据库中的问题...
  20. ppt背景图片php,求ppt背景,ppt背景图片,漂亮一些的。

热门文章

  1. 计算机绘图实训日志通用篇,cad制图实习日记范文:
  2. 吴恩达机器学习课程笔记——第二周
  3. [bzoj4919] 大根堆
  4. 2 台电脑共享键鼠最简单教程
  5. 机器学习基本库之Pandas
  6. 【工作汇报220718】蛇形机器人的设计与研究的工作汇报记录
  7. RetinaFace人脸检测
  8. yum和dnf安装安全更新
  9. 智能控制技术_基于Matlab的二阶系统模糊控制仿真实例_课程学习
  10. react组件深度解读