membersound
membersound

Reputation: 86687

Passing null as argument in overloaded methods?

It there a solution in java for the following type of problem: having an overloaded method that differs in one parameter. What do to if the differing parameter is passed in as null?

class PersonFactory {
    public static Person create(String firstname, String lastname, String age) {
          return create(firstname, lastname, Integer.valueOf(age));
    }

    public static Person create(String firstname, String lastname, Integer age) {
           Person p = new Person();
           p.setFirstname(firstname);
           p.setLastname(lastname);
           p.setAge(age);
           return p;
    }
}

PersonFactory.get("John", "Doe", null); //ambigous mapping

I thought one could pass an Optional.empty() here, but which has no defined type and thus cannot be used to chose the correct method...

Upvotes: 0

Views: 181

Answers (2)

Andy Turner
Andy Turner

Reputation: 140319

This is only an issue if you are passing literal null.

Consider adding another overload with just 2 parameters, to avoid you having the call-site cruft of a) null; b) the disambiguating null cast suggested by marstran:

public static Person create(String firstname, String lastname) {
  return create(firstname, lastname, (Integer) null);
  // Or (String), if that's the one you want to invoke.
}

null by itself (or with a cast) isn't very meaningful to readers of the code.

An alternative with your existing overloads is to define a constant:

public static final Integer MISSING_AGE = null;

// ...
Person.create(firstname, lastname, MISSING_AGE)

You can choose a name for this constant which accurately conveys the semantics of a null parameter value:

  • Withheld age
  • Unknown age
  • Zero age
  • Default age
  • Create now without an age but one will be provided later
  • ...

(similarly, the 2-arg create method suggested above should be named to convey what it means not to provide an age).


Notwithstanding the above, you wouldn't have this issue if you didn't have the String overload. I assume you have the String overload for convenience: you don't need to be so "kind" to callers of your API.

As it stands, it's unclear what String values you would accept: do you accept spaces? Comma separation of thousands? Hex? etc.

Let the caller deal with those questions: if all you accept is an Integer, they are the ones who have to work out how to construct that.

That's possibly easier for them, since they know more about their data than you, and they find your API easier to understand. And it's easier for you, because you have a smaller API surface to maintain.

Upvotes: 3

marstran
marstran

Reputation: 27971

You need to cast null to the type you want so that the compiler can resolve the ambiguity.

For example:

PersonFactory.get("John", "Doe", (String) null);

or

PersonFactory.get("John", "Doe", (Integer) null);

Upvotes: 6

Related Questions