static 修饰符能够与变量、方法一起使用,表示是“静态”的。

静态变量和静态方法能够通过类名来访问,不需要创建一个类的对象来访问该类的静态成员,所以static修饰的成员又称作类变量和类方法。静态变量与实例变量不同,实例变量总是通过对象来访问,因为它们的值在对象和对象之间有所不同。

请看下面的例子:

 1 public class Demo {
 2     static int i = 10;
 3     int j;
 4     Demo() {
 5         this.j = 20;
 6     }
 7     public static void main(String[] args) {
 8         System.out.println("类变量 i=" + Demo.i);
 9         Demo obj = new Demo();
10         System.out.println("实例变量 j=" + obj.j);
11     }
12 }

运行结果:

类变量 i=10
实例变量 j=20

static 的内存分配

静态变量属于类,不属于任何独立的对象,所以无需创建类的实例就可以访问静态变量。之所以会产生这样的结果,是因为编译器只为整个类创建了一个静态变量的副本,也就是只分配一个内存空间,虽然有多个实例,但这些实例共享该内存。实例变量则不同,每创建一个对象,都会分配一次内存空间,不同变量的内存相互独立,互不影响,改变 a 对象的实例变量不会影响 b 对象。

请看下面的代码:

 1 public class Demo {
 2     static int i;
 3     int j;
 4     public static void main(String[] args) {
 5         Demo obj1 = new Demo();
 6         obj1.i = 10;
 7         obj1.j = 20;
 8
 9         Demo obj2 = new Demo();
10
11         System.out.println("obj1.i=" + obj1.i + ", obj1.j=" + obj1.j);
12         System.out.println("obj2.i=" + obj2.i + ", obj2.j=" + obj2.j);
13     }
14 }

运行结果:

obj1.i=10, obj1.j=20
obj2.i=10, obj2.j=0

注意:静态变量虽然也可以通过对象来访问,但是不被提倡,编译器也会产生警告。

上面的代码中,i 是静态变量,通过 obj1 改变 i 的值,会影响到 obj2;j 是实例变量,通过 obj1 改变 j 的值,不会影响到 obj2。这是因为 obj1.i 和 obj2.i 指向同一个内存空间,而 obj1.j 和 obj2.j 指向不同的内存空间,请看下图:


图1  静态变量内存分配

注意:static 的变量是在类装载的时候就会被初始化。也就是说,只要类被装载,不管你是否使用了这个static 变量,它都会被初始化。

小结:类变量(class variables)用关键字 static 修饰,在类加载的时候,分配类变量的内存,以后再生成类的实例对象时,将共享这块内存(类变量),任何一个对象对类变量的修改,都会影响其它对象。外部有两种访问方式:通过对象来访问或通过类名来访问。

静态方法

静态方法是一种不能向对象实施操作的方法。例如,Math 类的 pow() 方法就是一个静态方法,语法为 Math.pow(x, a),用来计算 x 的 a 次幂,在使用时无需创建任何 Math 对象。

因为静态方法不能操作对象,所以不能在静态方法中访问实例变量,只能访问自身类的静态变量。

以下情形可以使用静态方法:

  • 一个方法不需要访问对象状态,其所需参数都是通过显式参数提供(例如 Math.pow())。
  • 一个方法只需要访问类的静态变量。

读者肯定注意到,main() 也是一个静态方法,不对任何对象进行操作。实际上,在程序启动时还没有任何对象,main() 方法是程序的入口,将被执行并创建程序所需的对象。

关于静态变量和静态方法的总结:

  • 一个类的静态方法只能访问静态变量;
  • 一个类的静态方法不能够直接调用非静态方法;
  • 如访问控制权限允许,静态变量和静态方法也可以通过对象来访问,但是不被推荐;
  • 静态方法中不存在当前对象,因而不能使用 this,当然也不能使用 super;
  • 静态方法不能被非静态方法覆盖;
  • 构造方法不允许声明为 static 的;
  • 局部变量不能使用static修饰。

静态方法举例:

1 public class Demo {
2     static int sum(int x, int y){
3         return x + y;
4     }
5     public static void main(String[] args) {
6         int sum = Demo.sum(10, 10);
7         System.out.println("10+10=" + sum);
8     }
9 }

运行结果:

10+10=20

static 方法不需它所属的类的任何实例就会被调用,因此没有 this 值,不能访问实例变量,否则会引起编译错误。

注意:实例变量只能通过对象来访问,不能通过类访问。

静态初始器(静态块)

块是由大括号包围的一段代码。静态初始器(Static Initializer)是一个存在于类中、方法外面的静态块。静态初始器仅仅在类装载的时候(第一次使用类的时候)执行一次,往往用来初始化静态变量。

示例代码:

 1 public class Demo {
 2     public static int i;
 3     static{
 4         i = 10;
 5         System.out.println("Now in static block.");
 6     }
 7     public void test() {
 8         System.out.println("test method: i=" + i);
 9     }
10     public static void main(String[] args) {
11         System.out.println("Demo.i=" + Demo.i);
12         new Demo().test();
13     }
14 }

运行结果是:

Now in static block.
Demo.i=10
test method: i=10

静态导入

静态导入是 Java 5 的新增特性,用来导入类的静态变量和静态方法。

一般我们导入类都这样写:

1 import packageName.className; // 导入某个特定的类

1 import packageName.*; // 导入包中的所有类

而静态导入可以这样写:

1 import static packageName.className.methonName; // 导入某个特定的静态方法

1 import static packageName.className.*; // 导入类中的所有静态成员

导入后,可以在当前类中直接用方法名调用静态方法,不必再用 className.methodName 来访问。

对于使用频繁的静态变量和静态方法,可以将其静态导入。静态导入的好处是可以简化一些操作,例如输出语句 System.out.println(); 中的 out 就是 System 类的静态变量,可以通过 import static java.lang.System.*; 将其导入,下次直接调用 out.println() 就可以了。

请看下面的代码:

1 import static java.lang.System.*;
2 import static java.lang.Math.random;
3 public class Demo {
4     public static void main(String[] args) {
5         out.println("产生的一个随机数:" + random());
6     }
7 }

运行结果:

产生的一个随机数:0.05800891549018705

系列文章:

Java知多少(上)

Java知多少(中)

Java知多少(31)static关键字以及Java静态变量和静态方法相关推荐

  1. Java基础篇:static关键字

    目录: 一.静态类与非静态类: 二.静态方法与非静态方法: 三.静态变量与非静态变量的区别: 四.静态代码块与非静态代码块: 五.静态构造函数与非静态构造函数: 六.相关问题: Java中的stati ...

  2. Java讲课笔记12:static关键字

    文章目录 零.本讲学习目标 1.掌握静态变量的使用 2.掌握静态方法的使用 3.掌握静态代码块的使用 一.static关键字的用处 二.静态变量 1.静态变量的定义 2.静态变量的内存分配示意图 3. ...

  3. Java中final、static关键字的作用

    final关键字可用于三个地方: 用于修饰类.类属性和类方法. 被final修饰的类不能被继承,被final修饰的类属性和类方法不能被覆盖(重写): 一.final 1. final修饰变量: fin ...

  4. Java static(一) - 静态变量

    1.JVM运行时数据区域 java堆存放所有的对象实例,被所有线程共享. 方法区(永久代)与Java堆中一样,是各个线程共享都内存区域,它用于存储已经被虚拟机加载类的信息.常量.静态变量(static ...

  5. JAVA 静态变量与静态方法

    java中静态变量和静态方法分别有什么特点? 悬赏分:0 - 解决时间:2006-4-10 10:28 提问者: vv_clear - 二级 最佳答案 为什么问了两次?再贴上另一篇 Thinking: ...

  6. java中静态变量和静态方法分别有什么特点?

    java中静态变量和静态方法分别有什么特点? 悬赏分:0 - 解决时间:2006-4-10 10:28 提问者: vv_clear - 二级 最佳答案 为什么问了两次?再贴上另一篇 Thinking: ...

  7. java学习笔记(四)----对象、数组作为参数传递,静态变量、静态方法的使用,内部类,使用文档注释

    ***对象作为参数传递*** class passparam { int x;   public static void main(String[] args)   { passparam obj = ...

  8. 1.16 static关键字(静态变量和静态方法)

    在类中,使用 static 修饰符修饰的属性(成员变量)称为静态变量,也可以称为类变量,常量称为静态常量,方法称为静态方法或类方法,它们统称为静态成员,归整个类所有. 静态成员不依赖于类的特定实例,被 ...

  9. JAVA的静态变量、静态方法、静态类

    静态变量和静态方法都属于静态对象,它与非静态对象的差别需要做个说明. (1)Java静态对象和非静态对象有什么区别? 比对如下: 静态对象                                ...

  10. java 静态类 静态方法_JAVA的静态变量、静态方法、静态类

    静态变量和静态方法都属于静态对象,它与非静态对象的差别需要做个说明. (1)Java静态对象和非静态对象有什么区别? 比对如下: 静态对象                                ...

最新文章

  1. Java归去来第2集:利用Eclipse创建Maven Web项目
  2. 【通俗理解线性代数】 -- 特殊的矩阵
  3. 成功解决 pypmml.base.PmmlError: (‘PmmlException‘, ‘Not a valid PMML‘)
  4. LeetCode 47全排列Ⅱ48旋转图像
  5. 云炬Android开发笔记 16附加功能开发(二维码,一键分享,分页,搜索)
  6. JavaScript实现hammingDistance汉明距离算法(附完整源码)
  7. ITK:计算灰度图像的梯度幅度递推高斯
  8. ASP.Net Core Razor 部署AdminLTE框架
  9. Linux下解压缩命令
  10. LInux:shell 彩色进度条实现(有图有代码有真相!!!)
  11. 作者:王学志(1979-),男,中国科学院计算机网络信息中心副研究员。
  12. java JVM剖析
  13. 计算机在经济管理中的应用,现代经济管理中计算机技术的运用
  14. mysql游标嵌套怎么写,mysql游标和嵌套游标
  15. SQLyog 注册码记录
  16. linux基础ppt下载,《Linux基础》PPT课件.ppt
  17. SEO工具:免费快速排名软件大全!
  18. 解决mangos60级后生命值为什么不变
  19. (给3d人物模型添加原始动画文件 针对3d模型有动画文件 没有Avatar 没有Animator Controller)
  20. VS2012安装DirectX SDK(DXSDK_Feb10)

热门文章

  1. 九度OJ 1340:小A的计算器 (进制转换)
  2. Silverlight+WCF 新手实例 象棋 WCF通讯基础(十四)
  3. MyBaties入门
  4. 使用Vue做评论+localStorage存储(js模块化)
  5. 字符串低位优先排序真的只能排序字符串相同的字符么?
  6. [Unity3D]Unity3D圣骑士模仿游戏开发传仙灵达到当局岛
  7. Silverlight 设置DataGrid中行的提示信息
  8. cocos2d-x3.0 关于CCAnimate 的一些资料
  9. WPF XMAL获取元素的父元素,子元素
  10. 原型与继承学习笔记3