1

I have a small but very annoying bug.

Actually I am programming a family tree and some cases I search for a person but sometimes the person is not in the tree (makes sense). So my methods returns null.

The problem is when I try to do something like this.

familytree.getNode("Peter").getName();

Peter is not in the tree however he tries to get the Name and my code gives me a NullPointerException (makes sense again).

Though I dont know how to handle this kind of problem, I have a lot similar methods like getName()... For Example getGender(), getWife() etc.

I have two classes the familytree(with search, delete, etc. methods) and node (with all information about the person).

Maybe you guys have an idea!

EDIT:

For example this is my main method;

familytree.getNode("Fred").getGender(); //boolean

familytree.getNode("Max").getGender();

familytree.getNode("Peter").getGender();

familytree.getNode("Fe").getPartner(); //Partner Name

familytree.getNode("Freddyy").getName(); //String

How do I check for every case if its a nullpointer?

Nadax
  • 11
  • 5
  • Is `Node` a framework class or your own code? if the latter the best way was to return a dummy element instead of a `null`. – Timothy Truckle Dec 21 '16 at 15:38
  • @TimothyTruckle Well, "dummy" elements make sense sometimes; but here, it is hard. Defining "correct" semantics for an "empty" dummy person looks hard. I don't think that this is the natural, first solution here. – GhostCat Dec 21 '16 at 15:41
  • @GhostCat I'd say it is the perfect example of a useful Dummy element. The OP has lots of code througout the program that wants to access the getters on the elements. The only reason for the null-check is to display some replacement text which could also be taken from the dummy. – Timothy Truckle Dec 21 '16 at 15:45
  • @TimothyTruckle Then please explain the semantics of a "Dummy" person to me. How old is a dummy person? What is its name? How do you sort an array with 3 real and 7 dummy persons? On and on it goes. You are just moving the **real* issue into many different places now. All of a sudden, you have 50 methods that need special handling for dummy persons. – GhostCat Dec 21 '16 at 15:53
  • @GhostCat *"Then please explain the semantics of a "Dummy" person to me. How old is a dummy person? What is its name?"* if you'd get a `null`, what would you print out as name/age? what is the exact reason not to get those "null replacements" from the dummy? – Timothy Truckle Dec 21 '16 at 15:55
  • @TimothyTruckle If you get a null, you either throw an exception; or you put the code there that deals with it. That is the whole point: if the logic allows for empty results, then it has to be able to deal with that fact. That empty default person you suggest just *obscures* the real problem: the fact that he thinks he can get away without thinking about that "error case" when the person is actually not in his tree. – GhostCat Dec 21 '16 at 15:59
  • @GhostCat *"get away without thinking about that "error case""* that's the point: **is it** an *error case* as far as the logic is concerned? From what the OP wrote in her question I can't see this. – Timothy Truckle Dec 21 '16 at 16:03
  • Probably *error case* is the wrong word. But even then: he simply didn't design his interfaces to support this case. Introducing a dummy person to avoid NPEs will not fix his broken design. He has to step back and find a working end to end solution. Taking his comments so far, he simply does not **understand** what is wrong. That empty dummy person idea will thus not help him. – GhostCat Dec 21 '16 at 16:07

4 Answers4

3

If you are using java 8,instead of checking for null,try using the Optional

Maybe this topic can help you : Uses for Optional

At first using Optional may seem like more code,but in the end it's a lot cleaner and more effective.

Community
  • 1
  • 1
speXy
  • 53
  • 3
  • 1
    You are for sure right; but this guy has problems understanding that returning null requires to check for null. Not sure if Optionals will really work out for him. – GhostCat Dec 21 '16 at 15:43
  • No its not a problem to check ifs zero, the problem is how I avoid that null (objects) try to call some methods... – Nadax Dec 21 '16 at 15:48
  • 1
    @Nado You have been told **repeatedly** what to do. The thing is: your idea how to **implement** your application is simply **broken**. There is **no** point in you insisting "but I want to do it *this* way" ... because *this* your way **does not work**. Please accept reality, **read** the advise you asked us for ... and go with that. – GhostCat Dec 21 '16 at 15:57
  • Ok then please my edition in the question, and show me to handle this problem. – Nadax Dec 21 '16 at 16:02
  • @Nado: how often do we have to tell you that you **can not** keep your code as is? Your approach is **broken** and insisting "but i want to keep it that way" wastes your time ... and ours. The code you added *can* throw those NullPointerExceptions all over the place. You **must** rework your design to somehow deal with the fact that your lookups either return null, or an Optional that is empty. – GhostCat Dec 21 '16 at 16:09
2

Simple idea: don't do that!

If your method can return null, then you have to check for that, like:

Person p = familytree.getNode("Peter");
if (p != null) {
 do something with p.getName();
} else {
 tell user: Peter is not known!

Or, check upfront:

if (familytree.contains("Peter")) {
  p = familytree.getNode("Peter"); // will be save
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Yeah but then I would have to check everything when I try to get the Name – Nadax Dec 21 '16 at 15:40
  • 1
    Of course. Probably 25% of your life as Java programmer is to check for null values. If you design an interface that **allows** for returning null, then yes, you have to check **each and any** usage of that interface. The alternative is to come up with methods that never return null. Which is pretty hard for such kind of map/lookup code. – GhostCat Dec 21 '16 at 15:43
0

You should do something like

Node node = familytree.getNode("Peter");
if ( null == node ){

    return "non existant";
}

String name = node.getName();
Matt Clark
  • 27,671
  • 19
  • 68
  • 123
  • Yeah that would makes sense, but I have several methods, returns with boolens, nodes, strings etc. – Nadax Dec 21 '16 at 15:39
0

Edit: actually, you can return a default Node instead of null at FamilyTree#getNode when the node is not found, that should be the proper way to do it.


Or you can use Java8 Optional and decide at every call what to do if getNode was null:

The key is to modify the FamilyTree#getNode method using Optional.ofNullable and then use map and orElse to deal with possible null values, providing a default value or getting the actual property.

See this :

static class FamilyTree {
    private Map<String, Node> nodes = new HashMap<>();
    // put some values in this map

    Optional<Node> getNode(String key) {
        return Optional.ofNullable(this.nodes.get(key));
    }
}

static class Node {
    private boolean gender;
    private String partner;
    private String name;

    boolean getGender() {
        return this.gender;
    }

    String getPartner() {
        return this.partner;
    }

    String getName() {
        return this.name;
    }
}

@Test
public void test_nado() {
    FamilyTree familytree = new FamilyTree();

    familytree.getNode("Fred").map(Node::getGender).orElse(false); //boolean
    familytree.getNode("Max").map(Node::getGender).orElse(false);
    familytree.getNode("Peter").map(Node::getGender).orElse(false);
    familytree.getNode("Fe").map(Node::getPartner).orElse(""); //Partner Name
    familytree.getNode("Freddyy").map(Node::getName).orElse(""); //String
}
Sxilderik
  • 796
  • 6
  • 20
  • map tells the optional what to do with its value if it is not null (here use a getter), and to do nothing if it is null. orElse provides a default value if the optional value was null. – Sxilderik Dec 21 '16 at 16:45
  • As mentioned before: I fail to see how this really helps. Imagine you asking your coworker: "could you please look up X in the phone book and tell me his number?" And your coworker comes back and says "it is 000-000-000" because actually X is not in the phone book, and those zeros are the "empty person" default phone number --- do you think those numbers help you? Wouldnt it be better if you were told "X is not in the phone book" instead. Now **you** have to figure "oh, 000.... means that X is unknown". – GhostCat Dec 21 '16 at 20:23