0

Could someone please tell me what is the function of if (month == null) { return monthNumber; } in the code below. I saw this code at Java tutorial Oracle. I have deleted the if statement above and the code below works just fine. Is the if statement unnecessary or it is included for some reason unknown to me.

public class StringSwitchDemo {

public static int getMonthNumber(String month) {

    int monthNumber = 0;

    if (month == null) {
        return monthNumber;
    }


    switch (month.toLowerCase()) {
        case "january":
            monthNumber = 1;
            break;
        case "february":
            monthNumber = 2;
            break;
        case "march":
            monthNumber = 3;
            break;
        case "april":
            monthNumber = 4;
            break;
        case "may":
            monthNumber = 5;
            break;
        case "june":
            monthNumber = 6;
            break;
        case "july":
            monthNumber = 7;
            break;
        case "august":
            monthNumber = 8;
            break;
        case "september":
            monthNumber = 9;
            break;
        case "october":
            monthNumber = 10;
            break;
        case "november":
            monthNumber = 11;
            break;
        case "december":
            monthNumber = 12;
            break;
        default: 
            monthNumber = 0;
            break;
    }

    return monthNumber;
}

public static void main(String[] args) {

    String month = "";

    int returnedMonthNumber =
        StringSwitchDemo.getMonthNumber(month);

    if (returnedMonthNumber == 0) {
        System.out.println("Invalid month");
    } else {
        System.out.println(returnedMonthNumber);
    }
}
}
Jess
  • 107
  • 8
  • It's a check against the possibility of a `null` value been passed to the method. You could replace it with [`Ojbects.requireNonNull`](https://docs.oracle.com/javase/8/docs/api/java/util/Objects.html#requireNonNull-T-), but this will generate a `NullPointerException`. Basically, based on what the method seems to be trying to do, it would be required. – MadProgrammer Nov 26 '15 at 05:35

3 Answers3

3

It is necessary. If you don't have it and month passed is null, then you will end up with a NullPointerException here switch (month.toLowerCase()) {.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • Could you please tell me under what kind of circumstances does the month passed is NULL? your help is greatly appreciated – Jess Nov 26 '15 at 05:37
  • 2
    @Jess In you example, it doesn't but there is no guarantee that `null` will never be passed to `getMonthNumber` – MadProgrammer Nov 26 '15 at 05:38
  • @Jess - Take MadProgrammer's advice. Don't go by his name :P. As a thumb rule always assume that you will get `null` and then code. This will prevent unexpected exceptions :) – TheLostMind Nov 26 '15 at 05:41
  • @MadProgrammer Thank you so much for the help!! – Jess Nov 26 '15 at 05:54
  • 1
    @VinodMadyalkar Thank you too for your help!! – Jess Nov 26 '15 at 05:54
2

Depending on your actual use of the method, using the magic return value (0) to indicate an invalid argument may not be the best option.

It is, if the intent is for callers to test if the string is a valid month name, but callers must always check for a 0 return value. In that case, your if statement is needed, to return 0 for a null argument.

If callers are only supposed to call method with valid month names, then throwing an exception will be better, and in that case, throwing a NullPointerException is perfectly valid. You should document it, though:

/**
 * Returns the month number (1-12) of the given full month name.
 * 
 * @param month full name of month, e.g. {@code "january"}
 * @return month number (1-12)
 * @throws NullPointerException if {@code month} is null
 * @throws IllegalArgumentException if {@code month} is not a valid month name
 */
public static int getMonthNumber(String month) {
    switch (month.toLowerCase()) {
        case "january":   return 1;
        case "february":  return 2;
        case "march":     return 3;
        case "april":     return 4;
        case "may":       return 5;
        case "june":      return 6;
        case "july":      return 7;
        case "august":    return 8;
        case "september": return 9;
        case "october":   return 10;
        case "november":  return 11;
        case "december":  return 12;
        default: throw new IllegalArgumentException("Invalid month: " + month);
    }
}

If you don't want exceptions, and you're using Java 8, you might want to use the new Optional to force callers to check for special return value:

public static Optional<Integer> getMonthNumber(String month) {
    if (month != null)
        switch (month.toLowerCase()) {
            case "january":   return Optional.of(1);
            case "february":  return Optional.of(2);
            case "march":     return Optional.of(3);
            case "april":     return Optional.of(4);
            case "may":       return Optional.of(5);
            case "june":      return Optional.of(6);
            case "july":      return Optional.of(7);
            case "august":    return Optional.of(8);
            case "september": return Optional.of(9);
            case "october":   return Optional.of(10);
            case "november":  return Optional.of(11);
            case "december":  return Optional.of(12);
        }
    return Optional.empty();
}
Andreas
  • 154,647
  • 11
  • 152
  • 247
1

It's like having a crash barrier beside a road - nobody drives into them on purpose, so they aren't strictly necessary, but we put them there because when something goes unexpectedly wrong, they help control what happens. Crash barriers stop cars going far off the road and damaging other people or buildings.

In other words, it's unnecessary if everything goes correctly - and in your example everything can only work well - but in bigger code, many things don't go well. Lots of people work on it, lots of people use it in a hurry, or while tired, or without understanding it. Writing code as if things will go wrong, and then guarding against it is an idea known as "Defensive Programming", and checking that parameters passed into functions actually are what you think they should be can help make more reliable, make programs more resilient with fewer overall errors and with lower chance of security holes.

This question, the answers, and the links have more ideas about it - Basic defensive programming

Community
  • 1
  • 1
TessellatingHeckler
  • 27,511
  • 4
  • 48
  • 87