为了保留引用,声明一个非静态的嵌套类?

时间:2012-12-10 12:32:34

标签: java swing static inner-classes

假设我有JDialog的专门子类(称为BrushListDialog),其中我有一个JList。该列表使用自定义列表模型(扩展DefaultListModel<String>)和自定义单元格渲染器(扩展DefaultListCellRenderer)。为了便于阅读,我将这些类嵌套在主类中。

通常情况下,我会将这些类设为静态(我 为单元格渲染器执行此操作),但列表模型类具有以下方法:

private boolean showRemoveConfirmDialog(Object elem) {
    int option = JOptionPane.showConfirmDialog(BrushListDialog.this,
            elem + " is a default brush type.\nDo you want to allow the removal of such entries?",
            "Remove", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
    if (option == JOptionPane.YES_OPTION) {
        TYPES.clear();
        return true;
    }
    return false;
}

如您所见,它依赖于顶级类的实例来确定JOptionPane的显示位置。当然,BrushListDialog.this不能在静态上下文中调用,因此嵌套类不能是静态的。

我看到有三种处理方式(使用null代表showConfirmDialog中的第一个参数不是一个选项):

  1. 保持单元格渲染器静态,但为了能够调用BrushListDialog.this,使列表模型成为内部类。
  2. 使两个嵌套类都是静态的,并通过列表模型的构造函数传递当前的BrushListDialog实例。
  3. 使用Swing实用程序方法浏览组件并查找BrushListDialog的实例(在我看来这很黑)。
  4. 所以我问你:为了能够访问父对话框的实例,保持列表模型是非静态的吗?

    Source code for the two nested classes

2 个答案:

答案 0 :(得分:1)

我个人认为不需要将类重构为非静态的 - 我们不是在谈论这里的巨大开销,在实践中只是一个参考。鉴于此,它归结为更具可读性和可维护性的选项;我认为将代码保留在该类别中是最好的。

那就是说,如果你真的想让它静止,那么我会选择你在第一个选项上出现的第二个选项。

你添加的第三个听起来很糟糕 - 绝对远离那个。

答案 1 :(得分:1)

就JVM而言,选项(1)和(2)通常是相同的 - Java编译器隐式地创建对父类的引用和适当的构造函数。

我会根据是否需要在父类之外使用该类来确定静态vs嵌套决策。如果没有,那么使用嵌套类来避免必须显式地编写父引用代码 - 但要注意由不正确的访问说明符创建的隐式访问委托方法。

选项(3)听起来像是一个非常脆弱的黑客,我会不惜一切代价避免......