現象
byte b = 20; // OK: 20 是 int 字面量,但編譯器常量折疊確認在 byte 範圍內,隱式窄化
float f = 3.25F; // OK: F 後綴聲明為 float 字面量
// byte b2 = 200; // Error: 200 超出 byte 範圍
// float f2 = 3.25; // Error: 3.25 是 double 字面量,需強轉或加 F
核心規則
| 場景 | 規則 | 示例 |
| **字面量賦值** (常量表達式) | 編譯器檢查值是否在目標類型範圍內,**允許隱式窄化** | byte b = 20; // OK byte b = 200; // Error |
| **變量賦值** (非常量表達式) | **禁止隱式窄化**,必須強轉 | int i = 20; byte b = i; // Error byte b = (byte)i; // OK |
| **算術表達式結果** | byte/short/char 運算**自動提升為 int**,結果賦值需強轉 | byte a=1,b=2; byte c = a+b; // Error byte c = (byte)(a+b); // OK |
針對提問解析
byte b = 20; → 字面量 20 在 byte 範圍內,**編譯器常量折疊**直接生成 bipush 20 字節碼,無轉換指令。
float f = 3.25F; → F 後綴使字面量類型為 float,**非窄化賦值**,直接存儲。
byte b3 = b + b1; → b+b1 經整數提升為 int 相加,結果 int 賦值給 byte 屬於**變量賦值窄化**,需強轉。
float a2 = a + a1; → a+a1 兩個 float 相加,**結果類型仍為 float** (無提升至 double),直接賦值**無窄化**,編譯通過。
關鍵點總結
- **字面量有「常量折疊」特權**,編譯期可見值範圍則允許隱式窄化。
- **浮點運算不提升至 double**,
float + float = float,double + float = double。
- **整數運算提升至 int**,
byte + byte = int,short + int = int。