Leaking this in constructor
-
11-12-2019 - |
Question
The Controller
class is a singleton, which seems to be a special case allowing for safely passing this
to Controller
.
Netbeans gives
Configure "passing suspicious parameters in the constructor" hint
for controller.addObserver(this);
which makes me ask what the better technique would be, although I gather it's not a good approach.
package net.bounceme.dur.usenet.swing;
import java.util.Observable;
import java.util.Observer;
import java.util.logging.Logger;
import javax.mail.Folder;
import javax.swing.ListModel;
import net.bounceme.dur.usenet.controller.Controller;
import net.bounceme.dur.usenet.controller.MessageBean;
import net.bounceme.dur.usenet.controller.MessagesDefaultListModel;
public class MessageSelect extends javax.swing.JPanel implements Observer {
private static final Logger LOG = Logger.getLogger(MessageSelect.class.getName());
private Controller controller = Controller.getInstance();
private ListModel messages = new MessagesDefaultListModel();
private MessageBean messageBean = new MessageBean();
@SuppressWarnings("unchecked")
public MessageSelect() {
controller.addObserver(this);
initComponents();
messagesJList.setPrototypeCellValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
}
Solution
You are passing this
to an external class (Controller
) when the object hasn't been fully constructed. Controller
could then reference your object while its construction hasn't finished.
Most people work around this by using a factory method which creates the object first, then passes this
externally.
// private to force clients to use the static factory method
private MessageSelect() {
initComponents();
messagesJList.setPrototypeCellValue("xxx");
}
public static MessageSelect createInstance() {
MessageSelect instance = new MessageSelect();
instance.controller.addObserver(instance);
return instance;
}
Take a look at this excellent Brian Goetz article on safe object construction.
OTHER TIPS
Using this as parameter can be dangerous in the contructor because the object is not fully initialized
As from http://wiki.netbeans.org/Java_Hints
I guess the point is, the super class may try and access apart of the class which has not yet been intialised (or you later change during your own construction)