【问题标题】:Multiple instances v. single static instance多个实例与单个静态实例
【发布时间】:2011-11-14 12:08:33
【问题描述】:

假设我有这个自定义组件。它是JMenuItem 的子类,并且所有实例都使用相同的Font 对象,尽管没有一个共享相同的实例。例如,

public abstract class JFooMenuItem extends JMenuItem{
    public JFooMenuItem(final String title){
        super(title);
        setFont(new Font("Courier New", Font.BOLD, 12));
    }
}

现在,考虑到可能有多达 10 个以上的菜单项,将 Font 实例设为共享的 static 成员变量会更有效,还是当前设置(即上面的代码)只是很好(内存管理方面)?

【问题讨论】:

  • 如果内存不是很紧并且这不是一个很小的程序,那么这就是过早的优化。如果这些菜单项一直在创建,那么这样做的真正原因是构建时间。
  • @larsmans,是的..你是对的。我想我只是想在第一时间把它做好..
  • @larsmans - 我不认为这是一个过早的优化。这里的辩论是:protected Font font = new Font()public static final Font font = new Font()。我认为第二种选择在编码风格上要好得多。
  • @larsmans - 我也认为premature optimization 被过多地用作编码不佳的借口。如果他再写两个字,程序员的手就不会断了。过早的优化是在你已经达到合理的性能时编写一些快速的花哨算法,并因此错过最后期限。编写干净的代码不是一种优化,而是一种必需。
  • 当心:为配置子类化 JSomething 是不行的!仅当您必须添加功能和/或错误修复时,它们才会被使用,子类化。否则,请使用提供已配置组件的应用程序范围工厂。或者,如果应用程序中所有东西的外观应该相同,则将这些属性添加到 UIManager 可能是一种选择

标签: java oop memory-management coding-style static-members


【解决方案1】:

我会说使用一个命名实例,不是因为内存,而是因为如果您决定更改字体,则必须在 10+ 位置进行编辑。

public static final Font MENU_FONT = new Font("Courier New", Font.BOLD, 12);

编辑:即使您使用子类化,最好将其声明为public static final,因为Font 是常量。更清楚了。

【讨论】:

  • 实际上,我仍然只需要在1 位置进行编辑,因为所有菜单项都将继承JFooMenuItem...
  • 如果你要子类化,你将不得不再次使用一个命名实例:)
  • @mre 即便如此,它也可以被认为是一个常量,因此使用静态 final 字段是有意义的。老实说,我不会太担心内存开销。好的代码风格更重要,效率也随之而来。
【解决方案2】:

我相信与Font 的10 个实例相关的内存开销在这里不是真正值得关注的问题。但是,从代码风格来看,您的 Font 在此类型的所有实例中都是一个常量,因此我认为如果以这种方式处理您的代码会更具可读性。

【讨论】:

    【解决方案3】:

    每次实例化JFooMenuItem 时,您的代码都会构造一个新的Font 对象。

    如果将其设为静态成员,Font 只会分配一次。

    【讨论】:

    • 这正是我问题的重点。存储多个类似的 Font 实例与单个静态 Font 实例相比,内存管理是否很差?
    • @mre - 最好使用一个静态 Font 实例 - 更好的内存管理和代码风格。
    • @mre:当然是——它们不相似,它们是相同的。为什么要用 50 个相同的不可变对象填充内存?
    • @Eric,我不知道与几个非静态变量相比,缓存静态变量是否有很多内存开销..
    猜你喜欢
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 2014-02-03
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 2018-06-25
    • 1970-01-01
    相关资源
    最近更新 更多