Java static关键字
0. 静态变量
Java类中的静态变量不属于任何一个类实例化出来的对象(即该类所有实例化出来的对象共享使用该静态变量,进而静态变量不具有线程安全性)
private static int count; public static double temper;
|
- 静态变量:在类中,整个类的所有实例化对象共用一个
- 实例变量:每个实例化对象拥有
- 静态变量:它的值对所有的实例来说都相同
读取静态变量
静态变量由两种读取方法:
- 类名.变量名
- 实例化对象名.变量名(前提该类可以实例化)
惯用第一种方法来读取变量,不推荐第二种方法读取。
class Player { static int playerCount = 0; private String name;
public Player(String name) { this.name = name; playerCount++; } }
public class PlayerTestDrive { public static void main(String[] args) { System.out.println(Player.playerCount); Player one = new Player("at0m"); System.out.println(one.playerCount); } }
|
Tips
- 静态变量会在该类的任何 对象创建之前就完成初始化。
- 静态变量会在该类的任何静态方法执行之前就初始化。
- 静态的final变量是常数
1. 静态方法
和静态变量类似的,静态方法属于类而非实例。静态的方法不能调用非静态的变量,静态的方法也不能调用非静态的方法。
静态方法是我们需要公开出来的,无需创建一个实例由实例调用类中的方法。从某种角度而言这种方法减少了对象的创建,为堆节省了创建对象的空间。
Java的包装类和工具类包含了大量的静态方法,Java程序的入口点main方法就是一个静态的方法
public class WrongStaticMethod { String name; public void printMessage() { System.out.println("只有实例对象才能输出本条信息"); }
public static void main(String[] args) { WrongStaticMethod.name = "at0m"; WrongStaticMethod.printMessage(); WrongStaticMethod trueCase = new WrongStaticMethod(); trueCase.name = "at0m"; trueCase.printMessage(); System.out.println(Math.random()); } }
|
Tips
- 静态的方法应该用类的名称来调用,而不是用对象引用变量。
- 静态的方法可以直接调用而不需要堆上的实例
- 仅有静态方法的类,可以设置其构造函数为private,防止被初始化。
- 静态方法可以存取静态变量。
2.静态块
Java静态块中的代码,在Java ClassLoader将其装载到内存中时,所执行的语句。静态块主要用于初始化类的静态变量。大多用来加载创建类时创建静态资源。
在静态块中不能访问非静态变量,在一个类中可以有多个静态块(没有太大意义)。静态块只在装载到内存的时候执行一次。
class otherClass { static { System.out.println("otherClass class is loaded"); } }
class StaticSuper { static { System.out.println("super static block"); } StaticSuper(){ System.out.println("super constructor"); } }
public class StaticTests extends StaticSuper { static int rand; static { rand = (int) (Math.random() * 6); System.out.println("static block " + rand); } StaticTests() { System.out.println("constructor"); }
public static void main(String[] args) { System.out.println("in main"); StaticTests st = new StaticTests(); } }
|
上述代码执行后根据对象间的关系,输出以下内容
$ java StaticTests super static block static block 5 in main super constructor constructor
|
Tips
3.静态类
Java可以嵌套使用静态类,但是静态类不能用于嵌套的顶层。静态嵌套类的使用与其他顶层类一样,嵌套只是为了便于项目打包。
public class StaticExample { static { System.out.println("StaticExample static block"); name = "Test"; setCount(2); }
static { System.out.println("StaticExample static block2"); }
private static int count; public static String name;
public int getCount() { return count; }
public static void setCount(int count) { if (count > 0) { StaticExample.count = count; } }
public static int addInts(int i, int... js) { int sum = i; for (int x : js) sum += x; return sum; }
public static class MyStaticClass { public int count;
} }
public class TestStatic { public static void main(String[] args) { StaticExample.setCount(5);
StaticExample.name = "at0m"; StaticExample tmp = new StaticExample(); System.out.println(tmp.getCount()); System.out.println(StaticExample.name + " is same as " + tmp.name); System.out.println(StaticExample.name == tmp.name);
StaticExample.MyStaticClass myStaticClass = new StaticExample.MyStaticClass(); myStaticClass.count = 10;
StaticExample.MyStaticClass myStaticClass1 = new StaticExample.MyStaticClass(); myStaticClass1.count = 20;
System.out.println(myStaticClass.count); System.out.println(myStaticClass1.count); } }
|
上述代码执行后,输出的结果如下
$ java TestStatic StaticExample static block StaticExample static block2 5 at0m is same as at0m true 10 20
|
4.静态import
一般,Java允许用静态成员使用类引用,从Java1.5开始,我们可以使用静态import而不用类引用。
package com.journaldev.test;
public class A {
public static int MAX = 1000; public static void foo(){ System.out.println("foo static method"); } }
|
package com.journaldev.test;
import static com.journaldev.test.A.MAX; import static com.journaldev.test.A.foo;
public class B {
public static void main(String args[]){ System.out.println(MAX); foo(); } }
|
第2段代码用了import语句 import static
,后面跟着的是静态成员的全称。为了导入一个类中的所有的静态成员,可以这样写“import static com.journadev.test.A.*”,这只有在我们要多次使用一个类的静态变量时写,但这种写法会降低代码的可读性。
参考文章:
https://www.journaldev.com/1365/static-keyword-in-java