I’m writing an Android app currently and I have a higher level question about when to use a static method/field.
My app tracks time usage across different activities, each activity is an instance of a class. I need a method that can return all instances of this class.
Is it bad design to place a static method/field in my Activity class like so:
static ArrayList<Activity> allInstances;
public static void addToComprehensiveList(Activity a) {
if(allInstances == null)
allInstances = new ArrayList<Activity>();
allInstances.add(a);
}
public static ArrayList<Activity> getComprehensiveList() {
return allInstances;
}
What’s the correct design choice here?
Keeping a static list of instances is a fairly safe and normal thing to do. The main gotchas have to do with when you add items to the list.
For example, if
Activityhas a nontrivial constructor that callsaddToComprehensiveList(this)when it starts, then there are times when not-fully-initialized objects are in a publicly accessible list. If your program is single-threaded, this isn’t too dangerous – unless the constructor later throws an exception, in which case the object is left in the list in a not-fully-initialized state.A safe way around this is to create your instances in a factory method that adds the object to the list after it is created. Of course, if there are no subclasses, just adding to the list as the last statement in the constructor works fine.
The other danger here is that
getComprehensiveList()returns a reference to its instance list, which means that client code could be modifying that list without your class knowing. Even if the client just iterates through the list, you would get a commodification exception if you create a new Activity during their iteration. A safer approach is to return a copy of the list.