Chapter:Classes - Static members - Exercises

From Juneday education
Jump to: navigation, search

Exercises on static variables and methods

Let's go back to our Member class. We added a variable separator that we used to store the separator between values in our printout. We also discussed if we needed to have one separator variable per object. We don't. Instead we can let the class have a variable common for every object. This means that this variable belongs to (is associated with) the class instead of a separate object.

Q1

Change the separator variable into a class variable, using the keyword static.

Expand using link to the right to see a suggested solution/answer.

Suggested solution (parts of the class):

package net.supermegacorp.orgmanager;

public class Member {

  private String name;
  private String email;
  private static String separator = ";";

  public String toString() {
    return name + separator + email;
  }
}

Q2

Let's assume someone wants to know what separator is used when calling toString on Member objects. To let people get this value we can either:

  • make the variable public. A drawback of this is that people can change it. This makes it not usable for us.
  • keep the variable private and add a public method, getSeparator.

Your job is to write the method as described last. Should this method be public or private? Should it be static or non-static?.

Expand using link to the right to see a suggested solution/answer.

Suggested solution (parts of the class):

package net.supermegacorp.orgmanager;

public class Member {

  private String name;
  private String email;
  private static String separator = ";";

  public static String getSeparator() {
    return separator;
  }

  public String toString() {
    return name + separator + email;
  }
}

We need to make the method public since we want others to be able to use it. It does not have to be static since all objects can reach the class, but we suggest making it static to reflect that the variable is static.

Q3

Now, say that we want to change the value of the separator variable. Add a method, setSeparator(String separator), to change it.

Expand using link to the right to see a suggested solution/answer.

Suggested solution:

    public static void setSeparator(String separator) {
        Member.separator = separator;
    }

Q4

Can you motivate keeping the separator variable private when everyone can change it using the set method?

Expand using link to the right to see a suggested solution/answer.

The authors can not motivate Getters and Setters like this. But we will use the method in the next section so let's keep it for now.

Q5

Write a new class, StaticConfusion. Don't use any packages in this class (which makes the class get the nameless package). Write a main method that invokes the method email(). The class can look something like this:

import net.supermegacorp.orgmanager.Member;

public class StaticConfusion {

    public static void main(String[] args) {

        Member.email();

    }

}

Compile. Did it work? Why?

Expand using link to the right to see a suggested solution/answer.

The class StaticConfusion will not compile. You'll get an error message similar to this:

StaticConfusion.java:7: error: non-static method email() cannot be referenced from a static context
        Member.email();
              ^
1 error

The method email() is an instance method which means it is associated with an object. Calling the method with an association to the class and no object does not make sense. This is similar to asking the blueprint of a mobile phone what phone number is has - it is instances of the mobile phone blueprint that has phone numbers.

We have noticed that a common solution to this type of compiler error ("X cannot be referenced from a static context"), even among teachers and supervisors, is to make the method (in this case email()) static. Try doing this and you'll find that you also need to make the instance variable email static. Et voilà, it works. At least it compiles. The "only" problem now is that all Member instances will share the same email address.

We urge you not to fall in to the common pattern we (the authors) call 'the static swamp anti-pattern'. Think about if asking the class for an email address is wise in the first place and you'll realize that it isn't. Static members are for stuff which is static - known at compile time and shared between all instances. Another solution is to create or otherwise obtain a reference to an object of the type Member if you are interested in email addresses.

Choosing between instance or static level for a method or variable isn't obvious when beginning to learn Java. It will become clearer the more you practice and program. Review the videos if you are unsure, or checkout this PDF on Static or non-static which has a few rules of thumb. One way to address this is to make everything non-static until you find a need to make something static (like you discover that something isn't related to instances).

Links

Further reading

Where to go next

Next page is: Classes_-_final_members

« PreviousBook TOCNext »