在 Android 開發中,Activity 透過 Bundle 接收數據後,若直接用於初始化成員變量陣列(含內部類實例),常因初始化時機導致數據為 null。本文深度剖析此經典陷阱並給出正確模式。
public class ActivityB extends AppCompatActivity {
String A, B, C; // 從 Bundle 獲取
Map mMap = new HashMap<>();
// 內部類
class Util { String a, b, c; ... }
class Util2 { String a, b, c; ... }
// 成員變量陣列:類加載時初始化,此時 A/B/C 尚為 null
public Util[] u = { new Util(A, B, C), ... };
public Util2[] u2 = { new Util2("a", "b", "c"), ... };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
receive(); // 此時賦值 A/B/C
setArray(); // 遍歷陣列,u 陣列內容為 null
}
}
u 陣列作為實例變量,在 onCreate() 執行前(構造函數階段)已完成初始化A/B/C 仍為預設值 null,導致 Util 構造函數接收到 nullUtil2 使用字面量 "a" 而非變量,故不受影響private void setArray() {
// 此時 A/B/C 已賦值
Util[] u = { new Util(A, B, C), new Util(A, B, C), ... };
Util2[] u2 = { new Util2("a", "b", "c"), ... };
for (Util util : u) { ... }
for (Util2 util2 : u2) { ... }
}
private Util[] getUArray() {
if (u == null) {
u = new Util[] { new Util(A, B, C), ... };
}
return u;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
receive();
// 重新構建陣列元素
u = new Util[] { new Util(A, B, C), new Util(A, B, C), ... };
setArray();
}
onCreate / onStart 等生命週期方法中,確保數據就緒後再構建lateinit (Kotlin) 或 @Nullable 註解輔助靜態分析理解 Java 初始化時機與 Android 生命週期的交互,是避免此類「明明有值卻取不到」問題的關鍵。