Java 正在泄漏此构造函数

Java 正在泄漏此构造函数,java,swing,Java,Swing,可能重复: 我想知道在构造函数中泄漏此问题是否适用于此实例,因为我认为构造函数必须调用setJMenuBar方法来完成其构造,下面是类实现: public class StaffManagerMainWindow extends JFrame implements ActionListener { public StaffManagerMainWindow(String title, Image icon) throws HeadlessException { ...

可能重复:

我想知道在构造函数中泄漏此问题是否适用于此实例,因为我认为构造函数必须调用setJMenuBar方法来完成其构造,下面是类实现:

public class StaffManagerMainWindow extends JFrame implements ActionListener {

    public StaffManagerMainWindow(String title, Image icon) throws HeadlessException {
        ...
        setJMenuBar();
    }

    private void setJMenuBar() {
        ...
        exitItem.addActionListener(this);
        ...
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

我认为建造师有漏洞。在对象的完全初始化之前,您将传递此消息

我认为构造器有漏洞。在对象的完全初始化之前,您将传递此消息

如果您的程序是多线程的,则在构造函数中泄漏此信息可能是一个问题。您将其交给exitItem,它可能在构造函数完成之前从另一个线程调用actionPerformed。这不好。它会严重破坏您的程序,尤其是在向图片中添加子类时

改为创建一个init方法和一个factory方法:

public class StaffManager {
    public static StaffManager create() {
        StaffManager staffManager = new StaffManager();
        staffManager.init();
        return staffManager;
    }

    private StaffManager() {
    }

    private void init() {
        // Add listeners here.
    }
}
编辑:因为Swing对象总是在事件分派线程上创建的,所以在这种情况下这不会有任何影响。尽管如此,我还是不喜欢这样做。

如果您的程序是多线程的,那么在构造函数中泄漏这个可能是一个问题。您将其交给exitItem,它可能在构造函数完成之前从另一个线程调用actionPerformed。这不好。它会严重破坏您的程序,尤其是在向图片中添加子类时

改为创建一个init方法和一个factory方法:

public class StaffManager {
    public static StaffManager create() {
        StaffManager staffManager = new StaffManager();
        staffManager.init();
        return staffManager;
    }

    private StaffManager() {
    }

    private void init() {
        // Add listeners here.
    }
}


编辑:因为Swing对象总是在事件分派线程上创建的,所以在这种情况下这不会有任何影响。尽管如此,我还是不喜欢这样做。

是的,它会漏水。为什么你的ActionListener不能是私有的?如果我将所有代码从setJMenuBar方法移到构造函数中,那么我会在构造函数中收到警告消息泄漏此消息,但对于我的情况,编译器不会抱怨任何事情。这只意味着对代码执行的静态分析是有限的-它只是检查你是否在方法调用。@finalilusion编译器只能解决这么多问题。它不可能在所有情况下都发出警告。是的,它会泄漏。为什么你的ActionListener不能是私有的?如果我将所有代码从setJMenuBar方法移到构造函数中,那么我会在构造函数中收到警告消息泄漏此消息,但对于我的情况,编译器不会抱怨任何事情。这只意味着对代码执行的静态分析是有限的-它只是检查你是否在方法调用。@finalilusion编译器只能解决这么多问题。它不可能在所有情况下都发出警告。那么为什么编译器没有发出任何警告消息呢?我从来没有听说过编译器检查泄漏的消息。这本身不是一个问题,它只是为问题打开了大门。您确定这是一个编译器警告,而不是您拥有的其他检查工具吗?你在用什么编译器?Java/Eclipse,哪个版本?只是好奇而已。@MarkoTopolnik:谢谢。Netbeans依赖javac进行编译。在Eclipse Helios中,构造函数中的这段代码不会引起警告:new JButton.addActionListenerthis;用Java6JavaC编译的,也没有警告。您使用的是什么Java版本?那么为什么编译器没有给出任何警告消息呢?我从来没有听说过编译器检查是否有泄漏的消息。这本身不是一个问题,它只是为问题打开了大门。您确定这是一个编译器警告,而不是您拥有的其他检查工具吗?你在用什么编译器?Java/Eclipse,哪个版本?只是好奇而已。@MarkoTopolnik:谢谢。Netbeans依赖javac进行编译。在Eclipse Helios中,构造函数中的这段代码不会引起警告:new JButton.addActionListenerthis;用Java6JavaC编译的,也没有警告。您使用的是什么Java版本?拜托,Kjetil,为什么任何法律代码都会在事件分派线程之外调用Swing回调?即使它这样做了,这本身也是个问题。我不知道这里的全部情况,但我猜这个类可能会在事件发生的同时在不同的线程中初始化。在任何情况下,这都是一个坏主意,特别是如果类是线程安全的。Swing UI类根据定义不是线程安全的-所有Swing代码都必须在事件调度线程上执行。所有事件监听器肯定都将在EDT上以独占方式执行。是否必须在事件调度线程上构造所有Swing对象?如果不是,问题就在这里。是的,所有Swing组件都应该在EDT上执行。谢谢你回答我的问题。来吧,Kjetil,为什么任何法律代码都会在事件调度线程之外调用Swing回调?即使它这样做了,这本身也是个问题。我不知道这里的全部情况,但我猜这个类可能会在事件发生的同时在不同的线程中初始化。在任何情况下,这都是一个坏主意,特别是如果类是线程安全的
根据定义,es不是线程安全的-所有Swing代码都必须在事件分派线程上执行。所有事件监听器肯定都将在EDT上以独占方式执行。是否必须在事件调度线程上构造所有Swing对象?如果不是,这个问题适用于这里。是的,所有Swing组件都应该在EDT上执行。谢谢您回答我的问题