静态与非静态详解

静态与static关键字的分析

前言

  本文将对静态与非静态的关系,以及与之密切相关的关键字static做一些总结分析。这里的静态,指以static关键字修饰的,包括类,方法,块,字段。非静态,指没有用static 修饰的。由于静态变量都只能在方法之外声明,所以这里不再考虑局部变量的问题。

总览

静态有一些特点:

  • 全局唯一,任何一次的修改都是全局性的影响。
  • 只加载一次,优先于非静态。
  • 使用方式上不依赖于实例对象。
  • 生命周期属于类级别,从JVM 加载开始到JVM卸载结束。

我们先来讨论静态方法、静态变量、静态块,静态类将留在最后。

静态方法

  毫无疑问,当一个方法被static修饰时,它便成为了一个静态方法。

  静态方法在可见的情况下(访问修饰符限定可访问)可以由类名直接调用。利用这一特性,我们可以将一些经常要使用的功能封装成静态方法放在工具类中,以便随时调用。

  静态方法只能访问静态的成员变量和方法,不能访问非静态的方法和变量。

静态变量

  被static修饰的变量被称为静态变量,他和静态方法一样可以使用类名在可见的情况下直接调用。利用这一特性,我们可以在类中设置静态变量,可以实现以下操作:

  • 所有可见类都可以访问修改静态变量而且不需要实例化对象,使用最多的还是工具类中设定的静态常量,他在工具类创建的时候就设定好数值并无法更改,从而将一些比较难以表示的量,如π,使用更简单的方法表示和使用。
  • 定义private静态变量,所有该类的对象在实例化时都有该静态变量的一份拷贝(注意拷贝的是地址),从而实现所有对象都可以访问和修改这个变量,实现共用。

静态块

 

  由于从属于类,声明在方法之外,所以也称为静态初始化块,此处需要和普通初始化块加以区别。

  静态初始化块在类没有实例化时也会执行。例如,若静态初始化块所在类中有main方法,,运行main方法时都会先将本类中所有静态初始化块从上到下先运行完毕,然后后再运行main方法中的语句。而普通初始化块就没有这待遇了,它只有在类实例化的时候才会执行。

  关于运行的先后顺序,初始化一个类时,会先将所有的静态初始化块从上到下执行完毕,然后再执行普通初始化块的语句,最后才执行构造方法中的语句。而若该类有父类时,需要先执行父类构造器再执行子类构造器,这时情况就更为复杂了,具体流程为

  1. 父类的静态初始化块
  2. 子类的静态初始化块
  3. 父类的初始化块
  4. 父类的构造函数
  5. 子类的初始化块
  6. 子类的构造函数

静态内部类

  显然,普通类是不能被static修饰的,但内部类可以。和静态方法一样,它可以在可见的情况下使用外部类类名来调取并初始化。而非静态内部类被死死的限制在了外部类内部,只能在外部类中初始化非静态内部类,但好像这里能在外面被初始化也不是一件能拿出来炫耀的事。

  非静态内部类能够访问外部类的静态和非静态成员。静态类不能访问外部类的非静态成员。他只能访问外部类的静态成员。

  静态内部类可以单独初始化,而普通内部类初始化必须在外部类初始化后使用外部类对象来调用并实例化。

题外话

  关于工具类中的静态变量和静态方法在其他类中的调用有一个需要注意的地方。当在文件中类的外部import static jav.lang.Math.*;时,所有Math类中的静态方法和静态变量都可以直接使用而不需要用Math这个类名去调取。但显然的一点是,此文件的所有类都不能再出现和Math类中被使用的静态变量和静态方法同名的变量和方法。

 

猜你喜欢

转载自www.cnblogs.com/hbc314/p/12301140.html