Java中的侦听器占用了多少资源?

2022-09-03 05:10:48

我是Java编程的新手,但经验丰富的C++程序员。我正在学习如何使用 swing 对 GUI 进行编程。我想知道ActionListeners的资源密集型(运行时和内存)是多少?对于在特定程序中应创建的侦听器总数,是否有一般准则?在性能受到影响之前有多少个?

我目前正在通过Deitel Developer Series Java for Programmers一书学习Java。在一个特定的例子中,他们有一个JRadioButtonItems数组作为类的私有变量。他们还创建了一个 ItemHandler 类,该类从 ActionListener 类扩展而来,该类对整个单选按钮数组进行线性搜索,以确定所选按钮并相应地更改程序的状态。数组中的所有单选按钮共享同一个操作侦听器。这似乎效率低下,无法对信息进行线性搜索,因此我重写了 ActionListener 类,以接受要在构造函数中修改的建议值,并为每个单选按钮提供自己的 ActionListener,并由构造函数传入建议的值,以避免执行线性搜索。哪种方法在性能方面会更好?我很抱歉听起来像个菜鸟,我只是试图养成一套用Java编程的良好习惯。附件中是代码的一个小示例。谢谢。

    /************************************************************************
    Original code in Deitel book with linear search of selected Radio button in Actionlistener
    ****************************************************************************/
    import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;


public class MenuTest extends JFrame{
    private final Color colorValues[] = {Color.BLACK, Color.WHITE, Color.GREEN};
    private JRadioButtonMenuItem colorItems[];      
    private ButtonGroup colorButtonGroup;


    public MenuTest(){
        super("Menu Test");
        JMenu fileMenu = new JMenu("File");

        JMenuBar bar = new JMenuBar();
        setJMenuBar(bar);
        bar.add(fileMenu);

        String colors[] = {"Black", "White", "Green"};
        JMenu colorMenu = new JMenu("Color");
        colorItems = new JRadioButtonMenuItem[colors.length];
        colorButtonGroup = new ButtonGroup();

        ItemHandler itemHandler = new ItemHandler();

        for(int count = 0; count < colors.length; count++){
            colorItems[count] = new JRadioButtonMenuItem(colors[count]);
            colorMenu.add(colorItems[count]);
            colorButtonGroup.add(colorItems[count]);
            colorItems[count].addActionListener(itemHandler);
        }

        colorItems[0].setSelected(true);
        fileMenu.add(colorMenu);
        fileMenu.addSeparator();

    }

    private class ItemHandler implements ActionListener{
        public void actionPerformed(ActionEvent event){
            for(int count = 0; count < colorItems.length; count++){
                if(colorItems[count].isSelected()){
                    getContentPane().setBackground(colorValues[count]);
                }
            }
        }
    }


    public static void main(String args[]){
        MenuTest menuFrame = new MenuTest();
        menuFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        menuFrame.setSize(600,400);
        menuFrame.setVisible(true);
        menuFrame.getContentPane().setBackground(menuFrame.colorValues[0]);
    }
}
    /************************************************************************
    My Code redefined version of Deitel's w/o linear search in ActionListener
    ************************************************************************/

        import java.awt.Color;
        import java.awt.event.ActionEvent;
        import java.awt.event.ActionListener;

        import javax.swing.ButtonGroup;
        import javax.swing.JFrame;
        import javax.swing.JLabel;
        import javax.swing.JMenu;
        import javax.swing.JMenuBar;
        import javax.swing.JMenuItem;
        import javax.swing.JRadioButtonMenuItem;

        public class MenuTest extends JFrame{
        private final Color colorValues[] = {Color.BLACK, Color.WHITE, Color.GREEN};
        private JRadioButtonMenuItem colorItems[];      
        private ButtonGroup colorButtonGroup;


        public MenuTest(){
            super("Menu Test");
            JMenu fileMenu = new JMenu("File");

            JMenuBar bar = new JMenuBar();
            setJMenuBar(bar);
            bar.add(fileMenu);

            String colors[] = {"Black", "White", "Green"};
            JMenu colorMenu = new JMenu("Color");
            colorItems = new JRadioButtonMenuItem[colors.length];
            colorButtonGroup = new ButtonGroup();

            ItemHandler itemHandler = new ItemHandler();

            for(int count = 0; count < colors.length; count++){
                colorItems[count] = new JRadioButtonMenuItem(colors[count]);
                colorMenu.add(colorItems[count]);
                colorButtonGroup.add(colorItems[count]);
                colorItems[count].addActionListener(new ItemHandler(colorValues[count]));
            }

            colorItems[0].setSelected(true);
            fileMenu.add(colorMenu);
            fileMenu.addSeparator();

        }

        private class ItemHandler implements ActionListener{
            private Color setColor;
            public ItemHandler(Color inColor){
                super();
                setColor = inColor;
            }
            public void actionPerformed(ActionEvent event){
                getContentPane().setBackground(setColor);
                repaint();
            }
        }
        public static void main(String args[]){
            MenuTest menuFrame = new MenuTest();
            menuFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            menuFrame.setSize(600,400);
            menuFrame.setVisible(true);
            menuFrame.getContentPane().setBackground(menuFrame.colorValues[0]);
        }
    }

答案 1

CPU 使用率:接近于零。仅当侦听器侦听的对象的状态发生更改时,才会调用侦听器。他们并没有真正“倾听”。它们正在侦听的对象在需要时调用它们。(注:这是一个简化)

内存使用情况:大多数操作列表没有状态。因此,总持久内存使用量是任何对象所需的最小值。在您的示例中,存在状态,因为您有一个 setColor 字段。但内存使用率很低。

IMO,听众效率很高,您可以根据需要使用任意数量。


答案 2

与它们所连接的组件相比,侦听器的成本非常低。仅仅拥有数百个侦听器不太可能对CPU或内存产生太大影响。但是,听众所做的总工作更为重要。如果发现性能问题,可以使用 CPU/内存探查器来识别和优化原因。它不是你应该担心太多预先需要担心的事情。


推荐