静态方法和单例模式的分析

2018-12-13  本文已影响0人  温驭臣

        我们在编程中经常会有这样的困惑,有些功能使用单例来解决,有些功能使用静态方法来解决,那静态方法和单例的原理和使用场景是什么呢?我们今天来把这件事情说清楚。

一,先看静态方法和非静态方法的区别?

        遇到很多程序员都有这样的理解就是静态方法先加载,非静态方法后加载,静态方法会一直存在于内存中,非静态方法不会。所以建议使用非静态方法。首先强调这个理解是错误的。

        首先我们先从内存上分析,当应用程序完成初始化后,CLR(CLR是公共语言运行库(Common Language Runtime)和Java虚拟机一样也是一个运行时环境,它负责资源管理(内存分配和垃圾收集等),并保证应用和底层操作系统之间必要的分离。CLR存在两种不同的翻译名称:公共语言运行库和公共语言运行时。)将在进程的可用空间给每个进程分配一个地址空间,这个地址空间就是托管堆。托管堆又分为多个区域,其中最重要的是垃圾回收堆(GC Heap)和加载堆(Loader Heap), GC Heap 用于存储对象实例,受GC管理。Loader Heap通过MethodTable表存储的最重要的信息就是元数据相关信息,例如基类型,静态字段,实现接口和所有方法等等。Loader Heap不收GC控制,其生命周期为从创建到销毁。也就是说一个类一旦被加载,这个类的静态和非静态方法都会存储到Load Heap的MethodTab表中,不收GC控制,它们都是第一次加载就会常驻内存中。

        静态方法和非静态方法的区别是什么?区别就在创建对象的时候,静态方法就一份,而非静态方法每new一个新对象就会把这个实例相关信息在GC Heap上复制一份,同时把new出的新对象放在堆栈上。堆栈指针指的地址是刚刚复制到GC Heap的内存地址。因此在方法调用速度上,静态方法要快一点,因为非静态方法要实例化,分配内存。

从编程历史上看,早期的结构化编程几乎所有的方法都是静态方法,引入实例化方法是面向对象编程以后的事情了,所以实例化方法不是解决运行效率问题,内存问题。是为了让开发更加模式化,面向对象化。

        从上面的分析就可以得出一个结论:1,静态方法和非静态方法是解决模式的区分。2,如果不考虑继承,多态或如果一个方法和它所在类的对象无关,就应该选择静态方法,比如工具类。        

二,单例模式和静态方法的区别?

        我们在工程中有时需要维护一份信息,比如系统运行时加载的一些配置属性,这些配置属性必须在应用整个生命周期中一直存在,而且是公共的,所以只需要一份就可以了。这时候我们就会考虑使用单例或者静态方法去维护这一份数据,但此时这一份数据又是通过面向对象的方式获取的我们就会使用单例。

        首先静态方法是基于类的,单例是基于对象的。如果解决模式是基于对象的就是用单例,否则使用静态方法。比如需要继承类,实现接口,需要延迟初始化,需要重写父类等要使用单例,第二,静态方法是面向过程的,单例是面向对象的。第三,静态属性变量不会被GC清除,所以单例的对象不会被GC清除,静态方法中产生的对象会随着静态方法执行完毕而被释放。

上一篇 下一篇

猜你喜欢

热点阅读