0

I have this trivial piece of code:

public ModelAndView postLoginPage(@ModelAttribute("user") User user, ModelMap model,
                                      HttpServletRequest req, HttpServletResponse res) {

  if (user != null) {
    logger.log(Level.INFO, "\n\n [*][*][*][*][*] user not null ");
    if (user.getUsername().equals("jon")){
      return new ModelAndView("echo", "user", user);
    }
  } else 
    return new ModelAndView("oops", "user", user);       
}

With a return nested in a double if. It seems java is complaining about this not being a viable return statement? Why is this an error?

3
  • 2
    What would that method return if getUsername() is not equals "jon"? Commented Jan 30, 2017 at 11:39
  • I've fixed the "obvious" compile error due to a missing ). I don't think the question was about that. Commented Jan 30, 2017 at 11:41
  • The error is quite explicite. There is a possibility to not return anything. PS: this code could return a NPE Commented Jan 30, 2017 at 11:41

3 Answers 3

6

There is not an explicit return on all control paths. Java does not allow that.

You need to deal with the case where user is not null and user.getUsername().equals("jon") is not true.

What is so special about "jon"?

Sign up to request clarification or add additional context in comments.

3 Comments

its a test name for the condition. So every if should have an else ?
Not necessarily no. But a function that's marked as anything other than void must always return a value.
@Bathsheba you deserve populist badge for this answer :)
2

Each method must be guaranteed to return the declared type for all possible input.

if (condition1) {
    if (condition2) {
        return a;
    }
} else {
    return b;
}

look, when condition1 is true and condition2 is false, there will be no return statement executed. This isn't allowed.

The possible solution is:

public ModelAndView postLoginPage(@ModelAttribute("user") User user, ModelMap model,
                                      HttpServletRequest req, HttpServletResponse res) {

    if (user != null) {
        logger.log(Level.INFO, "\n\n [*][*][*][*][*] user not null ");
        if (user.getUsername().equals("jon")){
            return new ModelAndView("echo", "user", user);
        }
    } else { 
        return new ModelAndView("oops", "user", user);       
    }
    return null;
}

Obviously this forces you to check if the returned value isn't a null by accident, as I understand that from you business logic perspective it's not really possible. Still a good programmer would check and throw an exception just in case.

1 Comment

But do mention the possibility of a null pointer exception at the call site.
0

When you mention any return type in the method signature apart from void, at the end of the method execution the method should return a value.

Your code is not obeying that rule.

Let's see what's happening in your code.

if (user != null) {

    // (1) inside if block       
} else 
     return new ModelAndView("oops", "user", user); 

If user is null then condition will be false so the execution control will be passed to else block which will return the instance of ModelAndView("oops", "user", user); so no issues.

If user is not null then the condition will be true so the execution control will be passed into the inside of (1) if block

In the inside of (1) if block the program will write the log and then execution control will be passed to 2nd if condition.

Now let's see the second condition,

if (user.getUsername().equals("jon")){ 
   return new ModelAndView("echo", "user", user);
}

Here if username equals to "jon" then condition will be true. Then the execution control will come inside of (2) if block. Here program control will execute new ModelAndView( "echo", "user", user ); and return the instance. No issues.

Here comes the tricking point if the username is not equals to "jon" then as no else is presented the execution control comes out of the (1) if block and reach the end of the method.

As there is no statements which return either the instance of ModelAndView or null the compiler will through an error.

So, I suggest you to deal what to be return if username is not equal to "jon" like below. And don't add return null; at the end as it may can cause some runtime exceptions;

public ModelAndView postLoginPage(@ModelAttribute("user") User user, ModelMap model,
                                      HttpServletRequest req, HttpServletResponse res) {

  if (user != null) { 

    logger.log(Level.INFO, "\n\n [*][*][*][*][*] user not null ");

    if (user.getUsername().equals("jon")){

       return new ModelAndView("echo", "user", user);
    } else{ // to avoid compilation error

      return new ModelAndView("user is not jon", "user", user);
    }

  } else 
    return new ModelAndView("oops", "user", user);       
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.