0

I know that java short-circuits its boolean evaluations. So if (false && true) wouldn't reach the true condition since java already knows the first is false.

I'm having a problem though. I have to check if the input is a positive integer and is lesser than another integer.

The condition looks like this:

    if (inputIsPositiveInteger(input) && inputIsLessThanSomeNumber(input,someNumber)) {
      doSomething();
    }

    boolean inputIsPositiveInteger(String input) {
      String regex = "[0-9]*";
      return input.matches(regex);
    }

    boolean inputIsLessThanSomeNumber(String input, String someNumber) {
      return (Integer.parseInt(input) < Integer.parseInt(someNumber));
    }

This throws a NumberFormatException if my input isn't an integer since I'm parsing the input to an Integer in the second condition. I thought if the first condition was false it would just exit the if statement.

Can anyone shed light on this?

java.lang.NumberFormatException: For input string: "a"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:492)
    at java.lang.Integer.parseInt(Integer.java:527)
    at com.akolopez.servlets.ProductServlet.inputIsLessThanStock(ProductServlet.java:94)
    at com.akolopez.servlets.ProductServlet.validateInput(ProductServlet.java:78)
    at com.akolopez.servlets.ProductServlet.doPost(ProductServlet.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

Edit: updated my post with the other methods. Edit2: I added a stack trace if it helps.

17
  • 3
    Can we see both of the methods too? And yes, you are correct, the if-statement will only run doSomething() if both methods return true. Which leads me to believe that the error is being thrown while running one of the methods. Commented Feb 12, 2014 at 2:20
  • I edited my original post with the two methods. Commented Feb 12, 2014 at 2:24
  • 3
    Your inputIsPositiveInteger will also accept empty string "" which can later cause NumberFormatException. Consider using + instead of *. Also can you post more details about thrown exception? Stack trace would be helpful. Commented Feb 12, 2014 at 2:29
  • 1
    Perhaps [0-9]+ would be a better regex since it forces the input to have at least one digit, while [0-9]* is satisfied by an empty string. Commented Feb 12, 2014 at 2:30
  • Oh. Right, but I'm still getting errors with random letters anyway. I don't understand why the short circuit evaluation isn't working. Commented Feb 12, 2014 at 2:31

2 Answers 2

2

Validate both arguments, input and someNumber:

void whatever(String input, String someNumber) {
    if (inputIsLessThanSomeNumber(input, someNumber)) {
        doSomething();
    }
}

boolean inputIsLessThanSomeNumber(String input, String someNumber) {
    if (inputIsPositiveInteger(input) && inputIsPositiveInteger(someNumber))
    {
        return (Integer.parseInt(input) < Integer.parseInt(someNumber));
    }

    return false;
}

boolean inputIsPositiveInteger(String input) {
    String regex = "[0-9]+";
    return input.matches(regex);
}
Sign up to request clarification or add additional context in comments.

2 Comments

I agree with this. The OP seems to not be checking the other number. Also + instead of * is a good suggestion. [0-9]* matches an empty String.
I +1 it as nice improvement but OP claims that reversing accepted characters by regex solves his problem so I am afraid it is not entire solution.
0

If you are not certain your input is going to be in the correct format, you need to catch that exception. For instance, you could do the following:

try {
    int x = Integer.parseInt(input);
    int y = Integer.parseInt(someNumber);
    if(x>0 && x<y) {
        doSomething();
    }
} catch(NumberFormatException e) {
    // One of the inputs is not a number.
}

It also seems to make sense to do this way because you care about the inputs as integers, so convert them to integers and then do your comparisons.

3 Comments

Using catch as part of logic is not best way to code and OP is clearly trying to avoid it by validating his input before using it in method which could throw Exception.
I disagree. In cases where you have no control over the situation (whether or not a string is in the proper format), exception handling is perfectly fine. In fact, compare the code above and it seems pretty clear that using exception handling is not only shorter, but is easier to understand.
OPs code can be rewritten in many ways which will be even more readable then handling exceptions. Other point is term of speed. Reusing compiled regex patterns is faster then creating and handling exceptions.

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.