处理Objects.requireNonNull()引发的NullPointerException的最佳方法是什么?

时间:2018-10-18 07:50:35

标签: java android nullpointerexception null

这种方法看起来很棒,但是,当将它与生产代码一起使用并将其用于可能为 为null的对象时,似乎很难。考虑我的例子:

public class ShowDialogTask extends AsyncTask<Void, Void, Void> {
    private WeakReference<Context> contextReference;

    public ShowDialogTask(Context context) {
        contextReference = new WeakReference<>(context);
    }

    @Override
    protected Void doInBackground(Void... voids) {
        ...do a long running task...
        return null;
    }

    @Override
    protected void onPostExecute(Void void) {
        super.onPostExecute(void);
        Context ctx = Objects.requireNonNull(contextReference.get(), "Context became null");
        AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
        builder.setTitle("Dialog title");
        builder.setCancelable(true);
        builder.create().show();
    }

在onPostExecute()函数中,我使用Objects.requireNonNull方法设置了局部变量对象ctx。我的问题是,要使contextReference.get()等于null有点麻烦,而且肯定会在生产中发生。

我想知道将这种功能用于生产目的的最佳方法。

我的第一个想法是将代码包装在try-catch中,但是到处都这样做似乎是不好的编程:

try {
    Context ctx = Objects.requireNonNull(contextReference.get(), "Context became null");
    AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
    builder.setTitle("Dialog title");
    builder.setCancelable(true);
    builder.create().show();
} catch (Throwable t) {
    Log.d(TAG, t.getMessage());
}

1 个答案:

答案 0 :(得分:5)

最好的处理方式?不要把它放在第一位。

捕获NullPointerException是您几乎绝不应该做的事情,除非您与写得不好的API进行交互。 NullPointerException是未经检查的异常,表示它表示编程错误:最好解决编程错误。

使用条件检查事物是否为空,如果有,则执行其他操作。

Context ctx = contextReference.get();
if (ctx != null) {
  // Use ctx.
} else {
  Log.d(TAG, "Context became null");
}

更笼统地说,抓捕Throwable几乎是绝不可能的事,因为您可能会抓捕并处理您不想要的事情,导致吞咽您不知道必须处理的问题。