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

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

相关文章

  • idea使用带provide修饰依赖导致ClassNotFound

    idea使用带provide修饰依赖导致ClassNotFound

    程序打包到Linux上运行时,若Linux上也有这些依赖,为了在Linux上运行时避免依赖冲突,可以使用provide修饰,本文主要介绍了idea使用带provide修饰依赖导致ClassNotFound,下面就来介绍一下解决方法,感兴趣的可以了解一下
    2024-01-01
  • 详解Spring bean的注解注入之@Autowired的原理及使用

    详解Spring bean的注解注入之@Autowired的原理及使用

    之前讲过bean注入是什么,也使用了xml的配置文件进行bean注入,这也是Spring的最原始的注入方式(xml注入).本文主要讲解的注解有以下几个:@Autowired、 @Service、@Repository、@Controller 、@Component、@Bean、@Configuration、@Resource ,需要的朋友可以参考下
    2021-06-06
  • SpringCloud Config配置加密解密用法解析

    SpringCloud Config配置加密解密用法解析

    这篇文章主要介绍了SpringCloud Config配置加密解密用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • 在SpringBoot中更改默认端口的方法总结

    在SpringBoot中更改默认端口的方法总结

    在本文中,小编将带大家学习如何在 Spring Boot 中更改默认端口,默认情况下,嵌入式 Web 服务器使用 8080端口来启动 Spring 引导应用程序,有几种方法可以更改该端口,文中介绍的非常详细,需要的朋友可以参考下
    2023-07-07
  • 详解SpringBoot缓存的实例代码(EhCache 2.x 篇)

    详解SpringBoot缓存的实例代码(EhCache 2.x 篇)

    这篇文章主要介绍了详解SpringBoot缓存的实例代码(EhCache 2.x 篇),具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • intellij idea中spring boot properties文件不能自动提示问题解决

    intellij idea中spring boot properties文件不能自动提示问题解决

    这篇文章主要介绍了intellij idea中spring boot properties文件不能自动提示问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • 基于Java编写emoji表情处理工具类

    基于Java编写emoji表情处理工具类

    这篇文章主要为大家详细介绍了如何基于Java编写一个emoji表情处理工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • Java设计模式之观察者模式

    Java设计模式之观察者模式

    本文详细讲解了Java设计模式之观察者模式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • java数据结构实现双向链表功能

    java数据结构实现双向链表功能

    这篇文章主要为大家详细介绍了java数据结构实现双向链表功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • 如何解决Could not transfer artifact org.springframework.boot问题

    如何解决Could not transfer artifact org.spri

    在Maven更新过程中遇到“Could not transfer artifact org.springframework.boot”错误通常是由于网络问题,解决方法是在Maven的设置中忽略HTTPS,添加特定语句后,可以正常下载依赖,但下载速度可能较慢,这是一种常见的解决方案,希望对遇到相同问题的人有所帮助
    2024-09-09

最新评论