CS 112
Spring 2022

Old version

This is the CS 112 site as it appeared on May 12, 2022.

Problem Set 3 FAQ

If you don’t see your question here, post it on Piazza or come to office hours! See the links in the navigation bar for both of those options.

  1. In Problem 2-1, it mentions that the constructor should take advantage of the error-checking code that is already present in the mutator methods. What does that mean?

    It means that rather than performing its own error-checking on the inputs, throwing an exception as needed, and assigning the inputs to the fields if the inputs are valid, the constructor should simply call the mutator methods to initialize the fields.

    For example, in the Rectangle class from lecture, we revised the constructor to call the mutators for its fields as follows:

    public Rectangle(int w, int h) {
        this.setWidth(w);
        this.setHeight(h);
    }
    

    This works because those mutator methods were written to error-check their inputs and throw an exception as needed. So if an input to the constructor is invalid, the corresponding mutator method will throw an exception, and that exception will keep the object from being created.

  2. In Problem 3, I’m still confused about the differences between static and non-static variables and methods. Can you clarify when we should use one or the other?

    Here are some relevant examples that may be helpful:

    • In the Card class that you are writing for Problem 5, most of the methods are non-static because they need to access one of the fields of a particular Card object. When using those methods from outside the class, you would need to prepend a particular Card object (e.g., c.getColor()).

    • In that same Card class, you will write one static method called isValidColor that takes a String like "red" and returns true or false. This method does not need to access the internals of a particular Card object (i.e., it never needs to say this.X for a field named X). Rather, everything it needs is either passed in as a parameter or is present in the static array called COLORS. As a result, we were able to make this method static. Because it is static, when you call it from outside the class, you need to prepend the class name (e.g., Card.isValidColor("red")).

    • In the Rectangle class, the width and height variables are non-static (i.e., they are fields), because each Rectangle object needs its own copy of those variables.

    • You could imagine adding a static variable to the Rectangle class to keep track of how many Rectangle objects have been created during one run of a given client program. This variable needs to be static because we need a single count for the class as a whole, rather than a separate count inside each Rectangle object. Slides that demonstrates the use of this static variable can be found here.

  3. In one of my methods for problem 4, I’m getting a NullPointerException, even though I am checking for the case in which the parameter is null. What am I doing wrong?

    Make sure that the first thing that your method checks for is a null value. You need to check for it by doing something like this:

    if (values == null) {
        ...            
    }
    

    Note that we use the == operator because null is a value that would be stored inside the variable itself, and thus testing for it is comparable to testing for a primitive value.

    Important: If you are combining the test for null with another test, make sure that the test for null comes first! For example, the following is not correct:

    // WRONG!
    if (values.length == 0 || values == null) {
        ...            
    }
    

    This won’t work if values is null, because the expression values.length will be evaluated first, and it will produce a NullPointerException when values is null.

    Instead, you should put the test for null first:

    // CORRECT
    if (values == null || values.length == 0) {
        ...            
    }
    

    This version works when values is null because when you have a boolean expression that uses the || operator and the test to the left of the || is true, the interpreter doesn’t even try to evaluate the boolean expression to the right of the ||.

  4. In Problem 5, I’m getting an error that says something like “Cannot make a static reference to the non-static method...” Do you know why I would be getting this?

    Don’t forget that non-static methods need a calling object – i.e., an object that comes before the dot when you call the method.

    When we call a static method from another class, we put the class name before the dot. However, this does not work for non-static methods. For example, you cannot write something like Card.getColor(), because getColor() is a non-static method. Instead, you need to do one of the following:

    • Put a calling object before the dot – the object that you want to operate on. For example, if c is the Card object whose value you need, you would write c.getValue().
    • If the line you are writing is part of another non-static method, and the method you are calling will operate on the same object as the current method, you should use the implicit parameter to call it: this.getColor().