!=null的正確使用心得——有些NullPointerException應該讓它報出來

前言:筆者之前不知道從哪裏學來的”好”習慣, 在引用引用類型的變量時總習慣性地先進行!=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亦然。

| 書到這裏想必讀者已經意識到了兩者的區別。

小結:

我們以後在考慮是否要加!=null判斷時,只需要考慮一個問題:如果當前引用爲null,是否應該讓程序再繼續運行下去,若爲“否”,就不要加,再看看本文標題的後半句話。

謝謝閱讀

發佈了41 篇原創文章 · 獲贊 10 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章