-3

I hope you doing well =)

I'm new to Java and currently, I started learning OOP not a long time ago.

I have a task with which I have a problem.

Add a setter for the name field so that if someone typed an empty value in the name field, or a value greater than 100 characters, then this call to the setter would be ignored, and the old value would be typed in the name field.

The first time I did this with the following code everything was fine when I ran it in Eclipse.

But when I ran it in the test app, it failed because for example the setName method on the input "dyqu" is setting the value of the "Walker" name field, and it should have been set to "dyqu".

public class SpaceShip {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if(this.name == null)
        this.name = name;
    }

    //Test output
    public static void main(String[] args) {
        SpaceShip ship = new SpaceShip();
        ship.setName("Walker");
        System.out.println(ship.getName()); //Should be Walker

        ship.setName("");
        System.out.println(ship.getName()); //Should be Walker, empty value ignored

        ship.setName("Voyager ".repeat(100));
        System.out.println(ship.getName()); //Should be Walker, too long value ignored
    }
}

Then I tried to change the code to this one:

   public void setName(String name) {
        if(this.name.length() < 0 && this.name.length() > 100)
        this.name = name;
    }

I got this error:

Exception in thread "main" java.lang.NullPointerException
    at SpaceShip.setName(SpaceShip.java:9)
    at SpaceShip.main(SpaceShip.java:16)

Unfortunately, I can't solve the issue on lines 9 and 16.

The input data for line 16 may change. I would be glad for a hint or advice. Thank you!

I solved this issue with the next code, thanks, everyone!

public void setName(String name) {
    if (!name.isBlank() && name.length() < 100) {
    this.name = name;
    }
}
  • 1
    You removed the check if name is null and just try to call methods on it, hence it will throw a NPE when null is passed. Also `this.name.length() < 0 && this.name.length() > 100` will never be true as the length of a String cannot be less than zero **and** greater than 100 at the same time. The length of a String in general can never be less than zero. – OH GOD SPIDERS Apr 28 '22 at 12:44
  • 3
    @OHGODSPIDERS The check is not applied to the passed argument but to the instance variable which is always `null` before the first method invocation. The misunderstanding here seems to be `this.name` vs `name`. – Izruo Apr 28 '22 at 12:46
  • Hi @OH GOD SPIDERS Unfortunately, it didn't help me, that's why I made a question. Thank you! – Orest Dymarchuk Apr 28 '22 at 12:48

2 Answers2

2

Your implementation:

 public void setName(String name) {
        if(this.name.length() < 0 && this.name.length() > 100)
        this.name = name;
    }

references this.name which is the currently stored value within the SpaceShip-object. However when an object is created without assigning default values either directly or by setting them in a constructor they'll be assigned a default value.

For object types like String this default value is null. You can't invoke methods (or anything really) on null.

What you should do instead is validating the input of the method by omitting the this in front of name:

 public void setName(String name) {
        if(name.length() < 0 && name.length() > 100)
        this.name = name;
    }

Then it's validating the method-argument-variable 'name'.


To iterate on the logical issue of the check. Your 'if' is only allowing a value to be set of it's either smaller than 0 or greater than 100 in length. A String which is not null can never be smaller than 0 and it's the other way around, the value should only be set when the value is inbetween the desired lengths: if( name != null && !name.isEmpty() && !name.length() > 100)

L.Spillner
  • 1,772
  • 10
  • 19
  • 1
    `name.length() < 0` this will never be `true` on a `String`. – Nexevis Apr 28 '22 at 12:47
  • @Nexevis Yes, it will never be. But my answer is more focused on why the NPE always occurs. – L.Spillner Apr 28 '22 at 12:49
  • @Nexevis Oh. Well maybe I should've paid a little more attention. I misunderstood the question to be more focused on why this exception occurs. Sorry, my bad. – L.Spillner Apr 28 '22 at 12:55
  • 1
    Nothing to apologize for, just wanted a correct answer, I upvoted it now that it answers the question fully – Nexevis Apr 28 '22 at 12:55
0
if(this.name.length() < 0 && this.name.length() > 100)

in your setName method is referring to

private String name;

in your class, the instance variable.
That's null right now.
That's why you're getting a null exception.

Also

this.name.length() < 0

doesn't make sense. A string will never have a length less than 0.

You want it like this

public void setName(String name) {
        if(name.length() == 0 || name.length() > 100)
        this.name = name;
    }
//name.length() == 0 checks for an empty string
// || means OR 
  • `if(name.length() == 0 || name.length() > 100)` is backwards, that means he will only set a new name when `name` is `0` or when it is longer than 100. He wants under 100 and over 0. – Nexevis Apr 28 '22 at 14:05
  • From what I understood he said this "...if someone typed an empty value in the name field, or a value greater than 100 characters, then..." we may be saying the same thing – javastudent Apr 28 '22 at 14:50
  • He said he wants to _ignore_ the setter if name is empty or value greater than 100. Right now your setter _sets_ the values in this situation and ignores the setter when under 100 and over 0. – Nexevis Apr 28 '22 at 14:56
  • Ahh I see what you're saying now. my code has to be ```if(name.length() != 0 && name.length() < 100)``` ignore this setter? – javastudent Apr 28 '22 at 15:05
  • Yeah exactly, though you might need a `name != null` in there too. – Nexevis Apr 28 '22 at 15:23
  • ahhh I see now. So if ```if(name.length() != 0 && name.length() < 100 && name != null)``` is met, the setter is not ignored from what I understand? – javastudent Apr 28 '22 at 16:44
  • Right yeah, but you need `name != null` to go first in the conditions because `name.length()` will throw an NPE if `name` is null. You need the conditions to [short circuit](https://stackoverflow.com/questions/8759868/java-logical-operator-short-circuiting). – Nexevis Apr 28 '22 at 16:58
  • Ahhh ok I understand. I didn't know about short circuiting and how order does matter. – javastudent Apr 28 '22 at 17:39