这种方法看起来很棒,但是,当将它与生产代码一起使用并将其用于可能为 为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());
}
答案 0 :(得分:5)
最好的处理方式?不要把它放在第一位。
捕获NullPointerException
是您几乎绝不应该做的事情,除非您与写得不好的API进行交互。 NullPointerException
是未经检查的异常,表示它表示编程错误:最好解决编程错误。
使用条件检查事物是否为空,如果有,则执行其他操作。
Context ctx = contextReference.get();
if (ctx != null) {
// Use ctx.
} else {
Log.d(TAG, "Context became null");
}
更笼统地说,抓捕Throwable
几乎是绝不可能的事,因为您可能会抓捕并处理您不想要的事情,导致吞咽您不知道必须处理的问题。