-5

This method seems pretty great, however, when using it with production code and using it for an object that might be null seems unwieldy. Consider my example:

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();
    }

In the onPostExecute() function, I set a local variable object ctx using the Objects.requireNonNull method. My problem with that is that it's a bit difficult for me to reproduce making the contextReference.get() equal to null, and it can definitely possibly happen in production.

I would like to know the best way to use this functionality for production purposes.

My first idea would be to wrap the code in a try-catch, but doing that everywhere seems like bad programming:

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());
}
gnat
  • 6,213
  • 108
  • 53
  • 73
hellaandrew
  • 823
  • 11
  • 23
  • 4
    `requireNonNull` is normally used for something that is supposed to _never_ be null. Not something that you expect sometimes to be null. – khelwood Oct 18 '18 at 07:52
  • Never catch runtime exception if you don't know what to do with them, only catch them if you can do something about it. Else you'll hide potential problems that will accumulate over time and that you will have a hard time fixing when everything stop working. – Nyamiou The Galeanthrope Oct 18 '18 at 10:23
  • @khelwood Thank you, I believe that is the clarification I was looking for. – hellaandrew Oct 18 '18 at 21:10

1 Answers1

5

The best way to handle it? Don't throw it in the first place.

Catching NullPointerException is something you should pretty much never do, unless you are interacting with a poorly-written API. NullPointerException is an unchecked exception, meaning that it indicates a programming error: it is better to fix the programming error.

Check if the thing is null, using a conditional, and do something different if it is.

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

On a more general note, catching Throwable is almost never the right thing to do, as you will likely catch and handle things you don't intend to, leading to you swallowing problems that you didn't know that you had to handle.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • Thank you! This is how I've been handling this regularly. I was just curious about the use-case of the Objects.requireNonNull. – hellaandrew Oct 18 '18 at 21:11