时间:2021-05-19
今天在csdn上看到一个关于static的帖子,里面的某个人的回复引起了我的注意。回复的大概意思是说:"面向对象里面的静态修饰是面向对象编程带来的垃圾产物,应尽量避免使用。"这句话大体能够体现static在大部分软件工程师眼里的尴尬地位,有一部分软件工程师除了在刚开始学习的时候,有使用过static外,就再也没有接触过static了。对此,我不得不说,这是一种遗憾。static是面向对象这个大家庭里面不可或缺的一员,少了它,面向对象的编程将少了许多的乐趣,多了许多烦扰。
一、什么是static修饰符
许多书和人都喜欢把static称之为静态,但我不喜欢这样称呼它,我更喜欢直接叫它static。因为我认为静态这两个字无法真正表达出static的真正作用。在程序中任何变量或者成员都是在编译时由系统自动分配内存来存储的,而用static修饰的成员会存储在一个static内存区中并且一直存在,直到程序退出内存才会释放这个空间,也就是只要程序在运行,那么这块内存就会一直存在。那么这样的设计有什么意义了?在面向对象的概念中,这样的设计可是十分有意义的!因为这样的设计,static可以用来区分成员变量、方法是属于类本身还是属于类实例化后的对象。有static修饰的成员属于类本身,没有static修饰的成员属于类的实例。
可能很多人还是不能理解,我在这边快速简单的写个例子吧。
class a{ public $aa = 1; public function aa(){ $this->aa += 1; echo $this->aa; }}class b{ public function bb(){ $aaa = new a(); $aaa->aa(); }}class c{ public function cc(){ $aaa = new a(); $aaa->aa(); }}$bbb = new b();$ccc = new c();$bbb->bb();echo '*******************';$ccc->cc();注:在"this->aa"里面的"->"是php调用方法的方式类似于java里面的"."
上面代码很简单相信大家都能理解,我就不解释了。运行后的结果是2*******************2。
上面的代码是没用static的情况,下面我就再写一个用了static的demo。
class a{ public static $aa = 1; public static function aa(){ self::$aa += 1; echo self::$aa; }}class b{ public function bb(){ a::aa(); }}class c{ public function cc(){ a::aa(); }}$bbb = new b();$ccc = new c();$bbb->bb();echo '*******************';$ccc->cc();注:"self::"和"::"是php中调用static修饰的成员的方式。里面的差异与本文要探讨的内容关系不大,咱不解释,有兴趣的可以自行研究。
最后的运行结果是2*******************3。这说明了,在static修饰下的成员变量$aa在第一次调用后并没有被释放,而是依然存在static内存块中,所有在第二次调用后输出的结果是3。因为第一次调用后的变量$aa从1变成了2,第二次调用的时候$aa还是2,所有二次调用后$aa变成了3。这就是static修饰的变量会一直存在的体现。同时,要记住在面向对象的编程中static修饰的成员不能直接调用非static修饰的成员。如果你知道了static的原理这个就很好理解了。拿java举例,用static修饰的成员,是专门存储在一个static内存区里面。非static修饰的成员是存储在堆内存里面。两者是分开存储的,所以要想在static修饰的成员里面调用非static修饰的成员,就必须跟在外面调用一样,先实例化,在调用。对于那为什么可以在非static修饰的成员里面直接调用static修饰的成员这个问题,我的解释是,你在类外面调用static成员时不也是可以不实例化类就直接调用吗?更何况在类里面了?
虽然可以在非static修饰的成员里面直接调用static修饰的成员,但是我强烈建议大家不要这么做!原因后面会提到。
二、什么时候使用static修饰符
理解了上面说的,你只是初步了解了static,要想更近一步的理解static,就要读懂这句话:"static可以用来区分成员变量、方法是属于类本身还是属于类实例化后的对象。有static修饰的成员属于类本身,没有static修饰的成员属于类的实例。"很多初学者会搞不懂类和类的实例有什么不同?类是抽象的存在,而类的实例是类具体化的存在。两者是有区别的,因此就会发生一种情况,那就是有些类实例化后没有任何意义,也就是说没有实例化的必要,只有作为类才有意义。这时候,就必须用static来修饰成员变量和方法,表明这些变量和方法只属于类本身。比如:在做一个项目的时候,一个合格的软件工程师都会封装一个公共方法类,将经常用的公共方法放在里面,以便随时在项目中调用。这时候,你会发现,这个公共方法类,并没有一个合适的具体化的实例可以来表示,只有作为类的时候,才有其意义。所以里面的公共方法都可以用static来修饰,以表示这些方法都属于类本身,就不需要每一次使用一个公共方法的时候都要实例化出一个具体的对象了。还有就是像做安全防范(sql注入过滤、xss过滤等)的时候,将其统一封装成一个Security类,里面的方法就需要用到static来修饰,不然难道每一次过滤都要实例化一次吗?再开一个堆内存空间?类似的还有语言包、缓存等等。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
一.在java中提供的一些修饰符,这些修饰符可以修饰类、变量和方法,在java中常见的修饰符有:abstract(抽象的)、static(静态的)、public
static:(静态修饰符)面向对象中static修饰的内容是隶属于类,而不是直接隶属于对象的,所以static修饰的成员变量一般称作类成员变量,而static
关键字static1.概述static是一种修饰符static是Java中表静态的关键字它可以修饰成员变量、成员方法、代码块被static修饰的成员变量或成员方
内容虚方法可以有实现体,若一个实例方法的声明中含有virtual修饰符,则称该方法为虚方法。使用了virtual修饰符后,不允许再有static、abstrac
(1)用于对静态字段、只读字段等的初始化。 (2)添加static关键字,不能添加访问修饰符,因为静态构造函数都是私有的。 (3)类的