!=null的正确使用心得——有些NullPointerException应该让它报出来
2016-09-07 18:21
615 查看
前言:笔者之前不知道从哪里学来的”好”习惯, 在引用引用类型的变量时总习惯性地先进行!=null非空判断, 说是这样可以防NullPointerException。渐渐地,我们就会慢慢体会到,程序运行是没错, 可是出来的结果却总是跟预期有出入, 这其实很有可能是我们!=null的错误使用造成的。
转载请注明出处:http://blog.csdn.net/u014158743/article/details/52462025
| 一个非常简单的例子, 在页面上显示一个最简单的ListView。我们故意注释掉mAdapter的初始化,让程序可能跑出NullPointerException。
| 让mAdapter进行!=null非空判断, 本意是避免空指针的产生,然而程序一跑,界面一片空白, 这显然不是我们想要的。
| 这种情况便是笔者以为不应该进行!=null非空判断的。我们的例子非常简单,就短短的几行代码, 我们凭经验一眼就能看出来缺少了适配器的初始化。但是, 在真正项目中,如果我们很多地方都错加了这样的!=null非空判断, 就很可能出现本文前言中所说的尴尬,结果却总是耗费大把的精力去找这样的小bug。
| 我们来简单地分析一下上面的例子, 其实
我们的本意是程序运行到这步的时候,适配器是完全可用的(即已经正确初始化),能添加数据源,然后被set到ListView上,最后被显示出来。如果适配器不可用(没有被初始化),程序应该停止, 因为再运行下去也只能是与预期不符的结果。
程序的意思:运行到这步的时候,如果mAdapter被正确初始化了,那我们才怎么怎么样,不然就直接怎么怎么样。
| 这不经让笔者想到了编译时异常和运行时异常的区别。
| 这是一个Dialog的封装类, 任意调用showDialog方法可以显示对应的dialog,调用DialogHelper.dissmiss()来关闭dialog。
| 在dissmiss方法中,笔者用!=null分别对ProgressDialog和AlertDialog做了判断。
| 这里两者的本意就完全一致了:如果当前初始化并在界面上显示的是ProgressDialog那就隐藏ProgressDialog,显示的是Dialog亦然。
| 书到这里想必读者已经意识到了两者的区别。
小结:
转载请注明出处: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,是否应该让程序再继续运行下去,若为“否”,就不要加,再看看本文标题的后半句话。
谢谢阅读
相关文章推荐
- win7系统:ireport启动报异常 java.lang.NullPointerException,java环境变量已经正确配置
- android中使用smack库时,遇到错误:java.lang.NullPointerException
- JavaWeb学习(5.5)---在Servlet使用getServletContext()获取ServletContext对象出现java.lang.NullPointerException(空指针)异常的解决办法
- 在Servlet使用getServletContext()获取ServletContext对象出现java.lang.NullPointerException(空指针)异常的解决办法
- 在Servlet使用getServletContext()获取ServletContext对象出现java.lang.NullPointerException(空指针)异常的解决办法
- layout使用继承TextView,Activity未使用,报java.lang.NullPointerException一例
- 使用myeclipse启动tomcat时出现这种错误“Could not publish to the server. java.lang.NullPointerException”
- 从零开始使用eclipse Ant脚本语言生成.h头文件:[javah] Exception in thread "main" java.lang.NullPointerException
- java.lang.NullPointerException Exception details are logged in Window > Show View > Error Log 正确解决方法
- Eclipse中使用butterknife出现nullPointerException
- 当使用smartupload上传组件出现java.lang.NullPointerException: charsetName
- 当在类中的 Parcelable 接口使用 ArrayList < customObject > android 系统: nullPointerException
- 使用Eclipse开发Android出现java.lang.NullPointerException错误的解决方法
- 在Servlet使用getServletContext()获取ServletContext对象出现java.lang.NullPointerException(空指针)异常的解决办法
- 在Servlet使用getServletContext()获取ServletContext对象出现java.lang.NullPointerException(空指针)异常的解决办法
- 使用@PersistenceContext获取EntityManager报NullPointerException异常
- Android使用butterknife注解出现nullPointerException解决
- [hadoop] map函数中使用FileSystem对象出现java.lang.NullPointerException的原因及解决办法
- 使用Butter Knife 框架时报NullPointerException(Android studio或者IntelliJ IEDA开发,eclipse结构工程)
- 在Servlet使用getServletContext()获取ServletContext对象出现java.lang.NullPointerException(空指针)异常的解决办法