!=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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章