Addressing your specific questions
- Is this a good and correct way to use WeakReferences, or is there a simpler way? I don't want the Value to prevent its listeners from getting cleaned up, or to manually break links when a listener is no longer needed by the UI/calculations/whatever.
See "Pros and Cons of Listeners as WeakReferences""Pros and Cons of Listeners as WeakReferences" on StackOverflow. BegemoT's answeranswer explains how using weak references changes the semantics. To prevent anyone from being surprised when using an anonymous class listener (which are common in UI frameworks like SWT), I recommend clearly documenting this semantic on the
addListener method. Also, in my experience, weak references are not as well known by many developers which further reiterates the need for documentation.
There's other fascinating corners to explore in weak references including
WeakHashMap, which uses a
ReferenceQueue to cleanup, as discussed another SO questionquestion with some facinating links. If you dive into WeakHashMap (perhaps wrapped as a Set using
Collections.newSetFromMap) at some point, as noted, Guava (Google's common java library) makes a case for using their
Because of their relative obscurity and behavior depending on when the GC will run, I personally shy away from weak references and use them sparingly.
- Use the interface List<...> or the actual implementation type ArrayList<...> when declaring the member mListeners?
- Initialize mListeners with an empty list at the member declaration, or in the constructor?
See "Should I initialize variable within constructor or outside constructor""Should I initialize variable within constructor or outside constructor" on StackOverflow. Where you can, I recommend initializing at declaration for clarity.
- Java already has an implementation for the Observer pattern in
java.util.Observable. This has found to be wanting in that you have to extend
Observable. As suggested in "Alternative to Java's Observable class?""Alternative to Java's Observable class?", Guava's
EventBusis a good alternative. I've used it before and recommend it for its ease of use and aide in decoupling code.
- Declare fields as final where you can. Use final fields where you can to help prevent potential issues in mutability. Qualify
- I was surprised to see the fields at the bottom of the class. For customary readability, fields are typically declared prior to the constructors.