# æ·±å
¥çè§£ static å
³é®å
static æ¯æä»¬æ¥å¸¸çæ´»ä¸ç»å¸¸ç¨å°çå
³é®åï¼ä¹æ¯ Java ä¸é常éè¦çä¸ä¸ªå
³é®åï¼static å¯ä»¥ä¿®é¥°åéãæ¹æ³ãåéæä»£ç åãéæå¯¼å
çï¼ä¸é¢æä»¬å°±æ¥å
·ä½èä¸èè¿ä¸ªå
³é®åï¼æä»¬å
ä»åºç¡å¼å§ï¼ä»åºæ¬ç¨æ³å
¥æï¼ç¶ååæå
¶åçãä¼åçã
## åè¯ static å
³é®å
### static 修饰åé
`static` å
³é®åè¡¨ç¤ºçæ¦å¿µæ¯ `å
¨å±çãéæç`ï¼ç¨å®ä¿®é¥°çåé被称为`éæåé`ã
```java
public class TestStatic {
static int i = 10; // å®ä¹äºä¸ä¸ªéæåé i
}
```
éæåéä¹è¢«ç§°ä¸ºç±»åéï¼éæå鿝å±äºè¿ä¸ªç±»ææçãä»ä¹ææå¢ï¼è¿å
¶å®å°±æ¯è¯´ï¼static å
³é®ååªè½å®ä¹å¨ç±»ç `{}` ä¸ï¼èä¸è½å®ä¹å¨ä»»ä½æ¹æ³ä¸ã

å°±ç®ææ¹æ³ä¸ç static å
³é®å廿乿¯ä¸æ ·çã

static å±äºç±»ææï¼ç±ç±»æ¥ç´æ¥è°ç¨ static 修饰çåéï¼å®ä¸éè¦æå¨å®ä¾åç±»è¿è¡è°ç¨
```java
public class TestStatic {
static int i = 10;
public static void main(String[] args) {
System.out.println(TestStatic.i);
}
}
```
**è¿éä½ éè¦çè§£å 个åéçæ¦å¿µ**
* å®ä¹å¨æé æ¹æ³ã代ç åãæ¹æ³`å¤`çåé被称为å®ä¾åéï¼å®ä¾åéç坿¬æ°éåå®ä¾çæ°é䏿 ·ã
* å®ä¹å¨æ¹æ³ãæé æ¹æ³ã代ç å`å
`çåé被称为å±é¨åéï¼
* å®ä¹å¨æ¹æ³åæ°`ä¸`çåéè¢«ç§°ä¸ºåæ°ã
详æ
åè
### static ä¿®é¥°æ¹æ³
static å¯ä»¥ä¿®é¥°æ¹æ³ï¼è¢« static ä¿®é¥°çæ¹æ³è¢«ç§°ä¸º`éææ¹æ³`ï¼å
¶å®å°±æ¯å¨ä¸ä¸ªæ¹æ³å®ä¹ä¸å ä¸ `static` å
³é®åè¿è¡ä¿®é¥°ï¼ä¾å¦ä¸é¢è¿æ ·
```java
static void sayHello(){}
```
ãJava ç¼ç¨ææ³ãå¨ P86 页æä¸å¥ç»å
¸çæè¿°
**static æ¹æ³å°±æ¯æ²¡æ this çæ¹æ³ï¼å¨ static å
é¨ä¸è½è°ç¨ééææ¹æ³ï¼åè¿æ¥æ¯å¯ä»¥çãèä¸å¯ä»¥å¨æ²¡æå建任ä½å¯¹è±¡çåæä¸ï¼ä»
ä»
éè¿ç±»æ¬èº«æ¥è°ç¨ static æ¹æ³ï¼è¿å®é
䏿¯ static æ¹æ³ç主è¦ç¨é**ã
å
¶ä¸æä¸å¥é常éè¦çè¯å°±æ¯ **static æ¹æ³å°±æ¯æ²¡æ this çæ¹æ³**ï¼ä¹å°±æ¯è¯´ï¼å¯ä»¥å¨ä¸ç¨å建对象çåæä¸å°±è½å¤è®¿é® static æ¹æ³ï¼å¦ä½åå°å¢ï¼çä¸é¢ä¸æ®µä»£ç

å¨ä¸é¢çä¾åä¸ï¼ç±äº `staticMethod` æ¯éææ¹æ³ï¼æä»¥è½å¤ä½¿ç¨ ç±»å.åéåè¿è¡è°ç¨ã
å æ¤ï¼å¦æè¯´æ³å¨ä¸å建对象çæ
åµä¸è°ç¨æä¸ªæ¹æ³ï¼å°±å¯ä»¥å°è¿ä¸ªæ¹æ³è®¾ç½®ä¸º staticã平常æä»¬è§çæå¤ç static æ¹æ³å°±æ¯ mainæ¹ æ³ï¼è³äºä¸ºä»ä¹ main æ¹æ³å¿
é¡»æ¯ static çï¼ç°å¨åºè¯¥å¾æ¸
æ¥äºãå 为ç¨åºå¨æ§è¡ main æ¹æ³çæ¶å没æå建任ä½å¯¹è±¡ï¼å æ¤åªæéè¿ç±»åæ¥è®¿é®ã
**static ä¿®é¥°æ¹æ³ç注æäºé¡¹**
* é¦å
第ä¸ç¹å°±æ¯æå¸¸ç¨çï¼ä¸ç¨å建对象ï¼ç´æ¥`ç±»å.åéå` å³å¯è®¿é®ï¼
* static ä¿®é¥°çæ¹æ³å
é¨ä¸è½è°ç¨ééææ¹æ³ï¼

* ééææ¹æ³å
é¨å¯ä»¥è°ç¨ static éææ¹æ³ã

### static 修饰代ç å
static å
³é®åå¯ä»¥ç¨æ¥ä¿®é¥°ä»£ç åï¼ä»£ç åå为两ç§ï¼ä¸ç§æ¯ä½¿ç¨ `{}` 代ç åï¼ä¸ç§æ¯ `static {}` éæä»£ç åãstatic 修饰ç代ç å被称为éæä»£ç åãéæä»£ç åå¯ä»¥ç½®äºç±»ä¸çä»»ä½å°æ¹ï¼ç±»ä¸å¯ä»¥æå¤ä¸ª static åï¼å¨ç±»å次被å è½½çæ¶åï¼ä¼æç
§ static 代ç åçé¡ºåºæ¥æ§è¡ï¼æ¯ä¸ª static 修饰ç代ç ååªè½æ§è¡ä¸æ¬¡ãæä»¬ä¼é¢ä¼è¯´ä¸ä¸ä»£ç åçå 载顺åºãä¸é¢æ¯éæä»£ç åçä¾å

static 代ç åå¯ä»¥ç¨æ¥**ä¼åç¨åºæ§è¡é¡ºåº**ï¼æ¯å 为å®çç¹æ§ï¼åªä¼å¨ç±»å è½½çæ¶åæ§è¡ä¸æ¬¡ã
### static ç¨ä½éæå
é¨ç±»
å
é¨ç±»ç使ç¨åºæ¯æ¯è¾å°ï¼ä½æ¯å
é¨ç±»è¿æå
·æä¸äºæ¯è¾æç¨çãå¨äºè§£éæå
é¨ç±»åï¼æä»¬å
çä¸ä¸å
é¨ç±»çåç±»
* æ®éå
é¨ç±»
* å±é¨å
é¨ç±»
* éæå
é¨ç±»
* å¿åå
é¨ç±»
`éæå
é¨ç±»`å°±æ¯ç¨ static 修饰çå
é¨ç±»ï¼éæå
é¨ç±»å¯ä»¥å
å«éææåï¼ä¹å¯ä»¥å
å«ééææåï¼ä½æ¯å¨ééæå
é¨ç±»ä¸ä¸å¯ä»¥å£°æéææåã
éæå
é¨ç±»æè®¸å¤ä½ç¨ï¼ç±äºééæå
é¨ç±»çå®ä¾å建éè¦æå¤é¨ç±»å¯¹è±¡çå¼ç¨ï¼æä»¥ééæå
é¨ç±»å¯¹è±¡çå建å¿
须便äºå¤é¨ç±»çå®ä¾ï¼èéæå
é¨ç±»çå®ä¾å建åªé便å¤é¨ç±»ï¼
å¹¶ä¸ç±äºééæå
é¨ç±»å¯¹è±¡ææäºå¤é¨ç±»å¯¹è±¡çå¼ç¨ï¼å æ¤ééæå
é¨ç±»å¯ä»¥è®¿é®å¤é¨ç±»çééææåï¼èéæå
é¨ç±»åªè½è®¿é®å¤é¨ç±»çéææåï¼
* å
é¨ç±»éè¦è±ç¦»å¤é¨ç±»å¯¹è±¡æ¥å建å®ä¾
* é¿å
å
é¨ç±»ä½¿ç¨è¿ç¨ä¸åºç°å
åæº¢åº
```java
public class ClassDemo {
private int a = 10;
private static int b = 20;
static class StaticClass{
public static int c = 30;
public int d = 40;
public static void print(){
//ä¸é¢ä»£ç 伿¥éï¼éæå
é¨ç±»ä¸è½è®¿é®å¤é¨ç±»å®ä¾æå
//System.out.println(a);
//éæå
é¨ç±»åªå¯ä»¥è®¿é®å¤é¨ç±»ç±»æå
System.out.println("b = "+b);
}
public void print01(){
//éæå
é¨å
æå¤çç±»ä¸çæ¹æ³ï¼è°ç¨éæå
é¨ç±»çå®ä¾æ¹æ³ï¼å±äºå¤é¨ç±»ä¸è°ç¨éæå
é¨ç±»çå®ä¾æ¹æ³
StaticClass sc = new StaticClass();
sc.print();
}
}
}
```
### éæå¯¼å
ä¸ç¥éä½ æ³¨æå°è¿ç§ç°è±¡æ²¡æï¼æ¯å¦ä½ 使ç¨äº `java.util` å
çå·¥å
·ç±»æ¶ï¼ä½ éè¦å¯¼å
¥ java.util å
ï¼æè½ä½¿ç¨å
¶å
é¨çå·¥å
·ç±»ï¼å¦ä¸

使¯è¿æä¸ç§å¯¼å
æ¹å¼æ¯ä½¿ç¨`éæå¯¼å
`ï¼éæå¯¼å
¥å°±æ¯ä½¿ç¨ `import static` ç¨æ¥å¯¼å
¥æä¸ªç±»æè
æä¸ªå
ä¸çéææ¹æ³æè
éæåéã
```java
import static java.lang.Integer.*;
public class StaticTest {
public static void main(String[] args) {
System.out.println(MAX_VALUE);
System.out.println(toHexString(111));
}
}
```
## static è¿é¶ç¥è¯
æä»¬å¨äºè§£äº static å
³é®åçç¨æ³ä¹åï¼æ¥çä¸ä¸ static æ·±å
¥çç¨æ³ï¼ä¹å°±æ¯ç±æµ
å
¥æ·±ï¼æ
¢æ
¢æ¥ï¼åæè¦å¤ï½
### å
³äº static çæå±ç±»
static æä¿®é¥°ç屿§åæ¹æ³é½å±äºç±»çï¼ä¸ä¼å±äºä»»ä½å¯¹è±¡ï¼å®ä»¬çè°ç¨æ¹å¼é½æ¯ `ç±»å.屿§å/æ¹æ³å`ï¼èå®ä¾åéåå±é¨åé齿¯å±äºå
·ä½ç对象å®ä¾ã
### static 修饰åéçåå¨ä½ç½®
é¦å
ï¼å
æ¥è®¤è¯ä¸ä¸ JVM çä¸ååå¨åºåã

* `èææºæ ` : Java èææºæ æ¯çº¿ç¨ç§æçæ°æ®åºï¼Java èææºæ ççå½å¨æä¸çº¿ç¨ç¸åï¼èææºæ 乿¯å±é¨åéçåå¨ä½ç½®ãæ¹æ³å¨æ§è¡è¿ç¨ä¸ï¼ä¼å¨èææºæ ç§å建ä¸ä¸ª `æ 帧(stack frame)`ã
* `æ¬å°æ¹æ³æ `: æ¬å°æ¹æ³æ 乿¯çº¿ç¨ç§æçæ°æ®åºï¼æ¬å°æ¹æ³æ åå¨çåºåä¸»è¦æ¯ Java ä¸ä½¿ç¨ `native` å
³é®åä¿®é¥°çæ¹æ³æåå¨çåºå
* `ç¨åºè®¡æ°å¨`ï¼ç¨åºè®¡æ°å¨ä¹æ¯çº¿ç¨ç§æçæ°æ®åºï¼è¿é¨ååºåç¨äºåå¨çº¿ç¨çæä»¤å°åï¼ç¨äºå¤æçº¿ç¨ç忝ã循ç¯ã跳转ãå¼å¸¸ã线ç¨åæ¢åæ¢å¤çåè½ï¼è¿äºé½éè¿ç¨åºè®¡æ°å¨æ¥å®æã
* `æ¹æ³åº`ï¼æ¹æ³åºæ¯å个线ç¨å
±äº«çå
ååºåï¼å®ç¨äºåå¨èææºå è½½ç 类信æ¯ã常éãéæåéã峿¶ç¼è¯å¨ç¼è¯åç代ç çæ°æ®ï¼ä¹å°±æ¯è¯´ï¼**static 修饰çåéåå¨å¨æ¹æ³åºä¸**
* `å `ï¼ å æ¯çº¿ç¨å
±äº«çæ°æ®åºï¼å æ¯ JVM 䏿大çä¸ååå¨åºåï¼ææç对象å®ä¾ï¼å
æ¬**å®ä¾åéé½å¨å ä¸**è¿è¡ç¸åºçåé
ã
### static åéççå½å¨æ
static åéççå½å¨æä¸ç±»ççå½å¨æç¸åï¼éç±»çå è½½èå建ï¼éç±»ç鿝èéæ¯ï¼æ®éæååéåå
¶æå±ççå½å¨æç¸åã
### static åºåå
æä»¬ç¥éï¼åºååçç®çå°±æ¯ä¸ºäº **æ Java 对象转æ¢ä¸ºåèåºå**ã对象转æ¢ä¸ºæåºåèæµï¼ä»¥ä¾¿å
¶è½å¤å¨ç½ç»ä¸ä¼ è¾æè
ä¿å卿¬å°æä»¶ä¸ã
声æä¸º static å transient ç±»åçåéä¸è½è¢«åºååï¼å 为 static 修饰çåéä¿å卿¹æ³åºä¸ï¼åªæå å
åæä¼è¢«åºååãè `transient` å
³é®åçä½ç¨å°±æ¯é²æ¢å¯¹è±¡è¿è¡åºååæä½ã
### ç±»å 载顺åº
æä»¬å颿å°äºç±»å 载顺åºè¿ä¹ä¸ä¸ªæ¦å¿µï¼static 修饰çåéåéæä»£ç åå¨ä½¿ç¨åå·²ç»è¢«åå§å好äºï¼ç±»çåå§å顺åºä¾æ¬¡æ¯
å è½½ç¶ç±»çéæå段 -> ç¶ç±»çéæä»£ç å -> åç±»éæå段 -> åç±»éæä»£ç å -> ç¶ç±»æååéï¼ééæå段ï¼
-> ç¶ç±»ééæä»£ç å -> ç¶ç±»æé å¨ -> åç±»æååé -> åç±»ééæä»£ç å -> åç±»æé å¨
### static ç»å¸¸ç¨ä½æ¥å¿æå°
æä»¬å¨å¼åè¿ç¨ä¸ï¼ç»å¸¸ä¼ä½¿ç¨ `static` å
³é®åä½ä¸ºæ¥å¿æå°ï¼ä¸é¢è¿è¡ä»£ç ä½ åºè¯¥ç»å¸¸çå°
```java
private static final Logger LOGGER = LogFactory.getLoggger(StaticTest.class);
```
ç¶èæ static å final 廿é½å¯ä»¥æå°æ¥å¿
```java
private final Logger LOGGER = LogFactory.getLoggger(StaticTest.class);
private Logger LOGGER = LogFactory.getLoggger(StaticTest.class);
```
使¯è¿ç§æå°æ¥å¿çæ¹å¼åå¨é®é¢
å¯¹äºæ¯ä¸ª StaticTest çå®ä¾å对象é½ä¼æ¥æä¸ä¸ª LOGGERï¼å¦æå建äº1000个 StaticTest 对象ï¼åä¼å¤åº1000个Logger 对象ï¼é æèµæºç浪费ï¼å æ¤é常ä¼å° Logger 对象声æä¸º static åéï¼è¿æ ·ä¸æ¥ï¼è½å¤åå°å¯¹å
åèµæºçå ç¨ã
### static ç»å¸¸ç¨ä½å便¨¡å¼
ç±äºå便¨¡å¼æçå°±æ¯å¯¹äºä¸åçç±»æ¥è¯´ï¼å®ç坿¬åªæä¸ä¸ªï¼å æ¤ static å¯ä»¥åå便¨¡å¼å®å
¨å¹é
ã
ä¸é¢æ¯ä¸ä¸ªç»å
¸çåéæ ¡éªéå®ç°å便¨¡å¼çåºæ¯
```java
public class Singleton {
private static volatile Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
```
æ¥å¯¹ä¸é¢ä»£ç åä¸ä¸ªç®åçæè¿°
ä½¿ç¨ `static` ä¿è¯ singleton å鿝éæçï¼ä½¿ç¨ `volatile` ä¿è¯ singleton åéçå¯è§æ§ï¼ä½¿ç¨ç§ææé å¨ç¡®ä¿ Singleton ä¸è½è¢« new å®ä¾åã
ä½¿ç¨ `Singleton.getInstance()` è·å singleton 对象ï¼é¦å
ä¼è¿è¡å¤æï¼å¦æ singleton 为空ï¼ä¼éä½ Singletion 类对象ï¼è¿éæä¸äºå°ä¼ä¼´ä»¬å¯è½ä¸ç¥é为ä»ä¹éè¦ä¸¤æ¬¡å¤æï¼è¿éæ¥è§£éä¸
å¦æçº¿ç¨ t1 æ§è¡å° singleton == null åï¼å¤æå¯¹è±¡ä¸º nullï¼æ¤æ¶çº¿ç¨ææ§è¡æäº¤ç»äº t2ï¼t2 å¤æå¯¹è±¡ä¸º nullï¼éä½ Singleton 类对象ï¼è¿è¡ä¸é¢ç夿åå®ä¾åè¿ç¨ã妿ä¸è¿è¡ç¬¬äºæ¬¡å¤æçè¯ï¼é£ä¹ t1 å¨è¿è¡ç¬¬ä¸æ¬¡å¤ç©ºåï¼ä¹ä¼è¿è¡å®ä¾åè¿ç¨ï¼æ¤æ¶ä»ç¶ä¼å建å¤ä¸ªå¯¹è±¡ã
## ç±»çæé 卿¯å¦æ¯ static ç
è¿ä¸ªé®é¢æç¸ä¿¡å¤§é¨åå°ä¼ä¼´é½æ²¡æèèè¿ï¼å¨ Java ç¼ç¨ææ³ä¸æè¿ä¹ä¸å¥è¯ **ç±»çæé å¨è½ç¶æ²¡æç¨ static 修饰ï¼ä½æ¯å®é
䏿¯ static æ¹æ³**ï¼ä½æ¯å¹¶æ²¡æç»åºå®é
çè§£éï¼ä½æ¯è¿ä¸ªé®é¢å¯ä»¥ä»ä¸é¢å 个æ¹é¢æ¥åç
* static æç®åãææ¹ä¾¿è®°å¿çè§åå°±æ¯æ²¡æ this å¼ç¨ãèå¨ç±»çæé å¨ä¸ï¼æ¯æéå«ç this ç»å®çï¼å 为æé æ¹æ³æ¯åç±»ç»å®çï¼ä»è¿ä¸ªè§åº¦æ¥çï¼æé å¨ä¸æ¯éæçã
* ä»ç±»çæ¹æ³è¿ä¸ªè§åº¦æ¥çï¼å 为 `ç±».æ¹æ³å`ä¸éè¦æ°å建对象就è½å¤è®¿é®ï¼æä»¥ä»è¿ä¸ªè§åº¦æ¥çï¼æé å¨ä¹ä¸æ¯éæç
* ä» JVM æä»¤è§åº¦å»çï¼æä»¬æ¥çä¸ä¸ªä¾å
```java
public class StaticTest {
public StaticTest(){}
public static void test(){
}
public static void main(String[] args) {
StaticTest.test();
StaticTest staticTest = new StaticTest();
}
}
```
æä»¬ä½¿ç¨ javap -c çæ StaticTest çåèç çä¸ä¸
```assembly
public class test.StaticTest {
public test.StaticTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."