简体   繁体   中英

Is there an alternative way for nested try and catch?

In the below posted code, I am tring to code a utility method and I want to check if an object is null or not and a string is null and not empty. so, I coded the way shown below with throwing some exception, but I think the code could have been coded in a better way because the way I coded it has nested try and catch blocks.and i do not think it is a good style

please guide me to better code the belwo method

code :

public static boolean isFragmentShowing(Activity activity, String tag) throws Exception {

    try {
        if (activity != null) {
            FragmentManager fragmentManager = FragmentUtils.getFragmentManagerInstance(activity);

            try {
                if (tag != null && !tag.equals("")) {
                    Fragment fragment = fragmentManager.findFragmentByTag(tag);

                    return (fragment != null && fragment.isVisible())? true : false;

                } else {
                    throw new NullPointerException("isFragmentShowing: fragment tag passed is null or empty");
                }
            } catch (NullPointerException e) {
                Log.e(TAG, "Error: " + e.getMessage().toString());
                System.exit(1);
                return false;
            }

        } else {
            throw new NullPointerException("isFragmentShowing: context reference is null");
        }
    } catch (NullPointerException e) {
        Log.e(TAG, "Error: " + e.getMessage().toString());
        System.exit(1);
        return false;
    }
}

There are two part of your application. One is request validation and another one is application logic. Separate request validation and application logic. It will be easier to read and maintains. Here is my try in bellow

public static boolean isFragmentShowing(Activity activity, String tag) throws Exception {

//validate request 
if(activity == null) {
    // throw exception or return value 
}   
if (tag == null && tag.equals("")){
    // throw exception or return value 
}
// rest of the part
FragmentManager fragmentManager = FragmentUtils.getFragmentManagerInstance(activity);
Fragment fragment = fragmentManager.findFragmentByTag(tag);
return (fragment != null && fragment.isVisible())? true : false;
}

If all you're going to do with the exception is

Log.e(TAG, "Error: " + e.getMessage().toString());

then you don't need the exception, you just need a string. As I said on your previous question, catching NullPointerException is rarely the correct thing to do; more generally, using exceptions for control flow is a pretty dubious practice. And using System.exit is rarely what you really want to do.

You can create a method something like:

boolean logMessageAndExit(String message) {
  Log.e(TAG, "Error: " + message);
  System.exit(1);
  return false;
}

and then call in your code like this:

if (activity == null) {
  return logMessageAndExit("isFragmentShowing: context reference is null");
}
if (tag != null && !tag.equals("")) {
  return logMessageAndExit("isFragmentShowing: fragment tag passed is null or empty");
}

Fragment fragment = fragmentManager.findFragmentByTag(tag);
return fragment != null && fragment.isVisible();

Returning a boolean here is a mere convenience to allow you to return it: this convinces the compiler that execution never goes past that line, even though the return is never really executed.

(You could make it return something Throwable instead, so you can throw logMessageAndExit , to make it more clear that it is abnormal).

Alright, here's how your isFragmentShowing method should be like. You see I've removed ALL of the try/catches . This is because your method already throws a checked Exception and the code calling your static method would need to wrap the call to isFragmentShowing inside the try/catch none the less. You can catch the NPE there quite easily and even print out its stack trace which would let you know which instance was essentially null . Either fragment or activity .
The only time we need to actually throw an NPE is when tag.equals("") returns true (since that won't throw an exception).
I've also replaced the last ternary operator return by just fragment != null && fragment.isVisible() since it means the same thing ( true is returned if the expression evaluates to true and false on the right is returned otherwise, why not the return the result of the expression itself?)

And here's the code:

public static boolean isFragmentShowing(Activity activity, String tag) throws Exception {
    FragmentManager fragmentManager = FragmentUtils.getFragmentManagerInstance(activity);

    if (tag.equals("")) {
        throw new NullPointerException("isFragmentShowing: fragment tag passed is empty");
    }

    Fragment fragment = fragmentManager.findFragmentByTag(tag);

    return fragment != null && fragment.isVisible();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM