Look at this code:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Greeter { | |
public String greetMessage(User user) { | |
if(StringUtils.isEmpty(user.email())) { | |
return null; | |
} | |
return "Hi, "+user.email(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class GreetPrinter { | |
public void static main(String[] args) { | |
User user = new User(); | |
if (args.length > 1) { | |
user.setEmail(args[0]); | |
} | |
Greeter greeter = new Greeter(); | |
String msg = greeter.greetMessage(user); | |
if (msg != null) { | |
System.out.println(msg); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class User { | |
private String email; | |
public void setEmail(String email) { | |
this.email = email; | |
} | |
public String email() { | |
return email; | |
} | |
} |
Can you count how many extra paths are there because of the null check? 2 extra conditions, and 1 extra collaborator (The StringUtils) to check for a null string.
Now look at the next code.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Greeter { | |
public String greetMessage(User user) { | |
return "Hi, "+user.email(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class GreetPrinter { | |
public void static main(String[] args) { | |
if (args.length < 1) { | |
throw new RuntimeException("No email"); | |
} | |
User user = new User(args[0]); | |
Greeter greeter = new Greeter(); | |
System.out.println(greeter.greetMessage(user)); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class User { | |
private String email = ""; | |
public User(String email) { | |
this.email = email; | |
} | |
public String email() { | |
return email; | |
} | |
} |
If you're still not convinced, listen to the guy who invented the null pointers:
http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare
I'm not 100% sure that returning an empty string will a difference. Of course, a not expected NPE won't happen, but there will be a check on the size of the returned string. In most of the cases the null is handled as an "error", but the empty string is not always and error. I suggest to use the null object pattern instead: http://www.clear.rice.edu/comp212/00-spring/handouts/week06/null_object_revis... With this approach it is pretty clear that an expected value hasn't been provided.
ReplyDeleteI absolutely agree! I just didn't want to mix that "rocket science" into the story just yet :D
ReplyDelete