通过案例了解静态修饰符static使用场景

 更新时间:2020年10月23日 11:54:17   作者:嘿熊  
这篇文章主要介绍了通过案例了解静态修饰符static使用场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

  今天在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来修饰,不然难道每一次过滤都要实例化一次吗?再开一个堆内存空间?类似的还有语言包、缓存等等。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Java中的Sort排序问题

    Java中的Sort排序问题

    这篇文章主要介绍了Java中的Sort排序问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • spring无法引入注解及import org.springframework.web.bind.annotation.*报错的解决

    spring无法引入注解及import org.springframework.web.bind.annota

    本文主要介绍了spring无法引入注解及import org.springframework.web.bind.annotation.*报错的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • 一次 Java 服务性能优化实例详解

    一次 Java 服务性能优化实例详解

    这篇文章主要介绍了一次 Java 服务性能优化实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • java使用FileVisitor遍历文件和目录

    java使用FileVisitor遍历文件和目录

    这篇文章主要为大家详细介绍了java使用FileVisitor遍历文件和目录,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • Java常用线程池原理及使用方法解析

    Java常用线程池原理及使用方法解析

    这篇文章主要介绍了Java常用线程池原理及使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Java countDownLatch如何实现多线程任务阻塞等待

    Java countDownLatch如何实现多线程任务阻塞等待

    这篇文章主要介绍了Java countDownLatch如何实现多线程任务阻塞等待,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Java实现限流接口的示例详解

    Java实现限流接口的示例详解

    限流是对某一时间窗口内的请求数进行限制,保持系统的可用性和稳定性,防止因流量暴增而导致的系统运行缓慢或宕机,本文主要来和大家聊聊如何使用java实现限流接口,感兴趣的可以了解下
    2023-12-12
  • Spring数据访问模板化方法

    Spring数据访问模板化方法

    今天小编就为大家分享一篇关于Spring数据访问模板化,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • java仿windows记事本功能完整版

    java仿windows记事本功能完整版

    这篇文章主要为大家详细介绍了java仿windows记事本功能完整版,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • SpringCloud应用骨架开发详解

    SpringCloud应用骨架开发详解

    这篇文章主要介绍了SpringCloud应用骨架开发详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09

最新评论