Leaking this in constructor

2019-06-06 04:09发布

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");
    }

2条回答
▲ chillily
2楼-- · 2019-06-06 04:26

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)

查看更多
够拽才男人
3楼-- · 2019-06-06 04:29

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.

查看更多
登录 后发表回答