前言:筆者之前不知道從哪裏學來的”好”習慣, 在引用引用類型的變量時總習慣性地先進行!=null非空判斷, 說是這樣可以防NullPointerException。漸漸地,我們就會慢慢體會到,程序運行是沒錯, 可是出來的結果卻總是跟預期有出入, 這其實很有可能是我們!=null的錯誤使用造成的。
轉載請註明出處:http://blog.csdn.net/u014158743/article/details/52462025
先看一個錯誤用法的例子:
package com.xinwo.adjusttemplate;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.xinwo.adjusttemplate.activity.BaseActivity;
public class MainActivity extends BaseActivity {
public ArrayAdapter<String> mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView listView = new ListView(this);
listView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
// mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line);
if (mAdapter != null) {
mAdapter.addAll(getResources().getStringArray(R.array.battery_level));
listView.setAdapter(mAdapter);
}
setContentView(listView);
}
}
| 一個非常簡單的例子, 在頁面上顯示一個最簡單的ListView。我們故意註釋掉mAdapter的初始化,讓程序可能跑出NullPointerException。
| 讓mAdapter進行!=null非空判斷, 本意是避免空指針的產生,然而程序一跑,界面一片空白, 這顯然不是我們想要的。
| 這種情況便是筆者以爲不應該進行!=null非空判斷的。我們的例子非常簡單,就短短的幾行代碼, 我們憑經驗一眼就能看出來缺少了適配器的初始化。但是, 在真正項目中,如果我們很多地方都錯加了這樣的!=null非空判斷, 就很可能出現本文前言中所說的尷尬,結果卻總是耗費大把的精力去找這樣的小bug。
| 我們來簡單地分析一下上面的例子, 其實if (mAdapter != null)
是違揹我們的本意的。
我們的本意是程序運行到這步的時候,適配器是完全可用的(即已經正確初始化),能添加數據源,然後被set到ListView上,最後被顯示出來。如果適配器不可用(沒有被初始化),程序應該停止, 因爲再運行下去也只能是與預期不符的結果。
程序的意思:運行到這步的時候,如果mAdapter被正確初始化了,那我們才怎麼怎麼樣,不然就直接怎麼怎麼樣。
| 這不經讓筆者想到了編譯時異常和運行時異常的區別。
正確用法的例子:
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Toast;
/**
* Created by swo
* on 16-8-31.
*/
public class DialogHelper {
private static AlertDialog dialog;
private static ProgressDialog progressDialog;
public static AlertDialog showListDialog(Context context, int arrayId){
.
.
dialog = new AlertDialog.Builder(context).
.
.
.create();
dialog.show();
return dialog;
}
public static void showWaitProgressDialog (Context context, String msg) {
progressDialog = new ProgressDialog(context);
progressDialog.setMessage(msg);
progressDialog.show();
}
public static void showClearDialog(final Context context, final boolean isClearDone) {
new AlertDialog.Builder(context).setMessage("確認刪除?")
.
.
.
.show();
}
public static void dismiss() {
if (progressDialog != null) {
progressDialog.dismiss();
}
if (dialog != null) {
dialog.dismiss();
}
}
}
| 這是一個Dialog的封裝類, 任意調用showDialog方法可以顯示對應的dialog,調用DialogHelper.dissmiss()來關閉dialog。
| 在dissmiss方法中,筆者用!=null分別對ProgressDialog和AlertDialog做了判斷。
| 這裏兩者的本意就完全一致了:如果當前初始化並在界面上顯示的是ProgressDialog那就隱藏ProgressDialog,顯示的是Dialog亦然。
| 書到這裏想必讀者已經意識到了兩者的區別。
小結: