Java类初始化难题

发布于 2024-10-06 19:23:47 字数 2027 浏览 4 评论 0原文

我使用 NetBeans 的 GUI 设计器创建一些 JDialog,然后从我自己的 EditorDialog 类中继承它们。

在进一步讨论之前,请考虑以下示例代码:

class MyDialog extends EditorDialog {
    private Color someVariableThatTheGuiNeeds = new Color(0,50,100);

    public MyDialog() {
        super(true);
    }

    //<auto-generated>
    private void initComponents() { //note this is private!
        //...
    }
    //</auto-generated>
}

abstract class EditorDialog extends JDialog {
    public EditorDialog() {
        super(null,true);
    }
    public EditorDialog(boolean stuffNeedsDone) {
        super(null,true);
        //initComponents();
        doStuffAfterGuiInitialized();
    }
}

问题是,我无法从我的超类中调用 initComponents(),因为它是私有的。

为了解决这个问题,我尝试了对类的解决方法:

//in EditorDialog
public EditorDialog(boolean stuffNeedsDone) {
    super(null,true);
    workaround();
    doStuffAfterGuiInitialized();
}
protected abstract void workaround();

//in MyDialog
@Override
protected void workaround() {
    initComponents();
}

当然,这不起作用,因为调用 initComponents()someVariableThatTheGuiNeeds 未初始化由于初始化发生的方式:

  • new MyDialog()
    • 超级(这个)
      • EditorDialog(boolean) 被调用
        • super(null,true) 被调用,JDialog 执行操作
        • EditorDialog 的实例变量已初始化
        • 解决方法()
        • initComponents()
          • doSomethingWith(someVariableThatTheGuiNeeds) -> NullPointerException 因为 someVariableThatTheGuiNeeds 尚未初始化
    • 现在 someVariableThatTheGuiNeeds 已初始化

另外,我无法创建非私有抽象EditorDialog 中的 initComponents(),因为覆盖时的可见性只能变得更加公开。

那么,我怎样才能解决这个问题,而又不会让它变得太黑客化呢?

(如果您不熟悉 NetBeans,我无法编辑自动生成的代码,并且没有(我能找到的)选项来更改 initComponents() 上的访问修饰符方法。

I am using NetBeans' GUI Designer to create some JDialogs, which I then subclass from my own EditorDialog class.

Before I go further, consider this sample code:

class MyDialog extends EditorDialog {
    private Color someVariableThatTheGuiNeeds = new Color(0,50,100);

    public MyDialog() {
        super(true);
    }

    //<auto-generated>
    private void initComponents() { //note this is private!
        //...
    }
    //</auto-generated>
}

abstract class EditorDialog extends JDialog {
    public EditorDialog() {
        super(null,true);
    }
    public EditorDialog(boolean stuffNeedsDone) {
        super(null,true);
        //initComponents();
        doStuffAfterGuiInitialized();
    }
}

The problem is, I can't call initComponents() from my superclass, because it is private.

To get around this, I tried a workaround to the classes:

//in EditorDialog
public EditorDialog(boolean stuffNeedsDone) {
    super(null,true);
    workaround();
    doStuffAfterGuiInitialized();
}
protected abstract void workaround();

//in MyDialog
@Override
protected void workaround() {
    initComponents();
}

And, of course, this doesn't work, because someVariableThatTheGuiNeeds isn't initialized when initComponents() gets called because of the way the initializations happen:

  • new MyDialog()
    • super(this)
      • EditorDialog(boolean) is called
        • super(null,true) is called, JDialog does stuff
        • EditorDialog's instance variables are initialized
        • workaround()
        • initComponents()
          • doSomethingWith(someVariableThatTheGuiNeeds) -> NullPointerException because someVariableThatTheGuiNeeds isn't initialized yet
    • NOW someVariableThatTheGuiNeeds is initialized

Also, I cannot create a non-private abstract initComponents() in EditorDialog, because the visibility when overriding can only become more public.

So, how can I get around this problem, without making it too hackish?

(If you are unfamiliar with NetBeans, I cannot edit auto-generated code, and there is no option (that I could find) to change access modifiers on the initComponents() method.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你怎么敢 2024-10-13 19:23:47

在任何情况下,您的构造函数都不应该调用非私有方法。如果您需要在创建对话框后对其进行初始化,则可以创建一个 init() 方法,该方法应在构造函数完成后调用。

请注意,方法名称 doStuffAfterGuiInitialized() 表示有点误解。 GUI,甚至实例,直到构造函数完成之后才完全初始化。

Your constructors shouldn't call non-private methods in any case. If you require initialization for your dialogs after they are created, you can create an init() method that should be called after the constructor is finished.

Note, the method name doStuffAfterGuiInitialized() indicates a bit of a misunderstanding. The GUI, or even the instance, isnt fully initialized until after the constructor completes.

满天都是小星星 2024-10-13 19:23:47

这是java中常见的问题。
实例化不是子类化的朋友。

许多人使用间接解决方案:在对象完全构建后调用 init() 方法。

这通常是通过工厂实现自动化的。
所有注入框架(如 Spring)都会例行执行此操作。

This is a problem that is common in java.
Instanciation is not a friend of subclassing.

An indirect solution is used by many : call an init() method once the object is fully build.

This is often automated via a factory.
All injection frameworks (like Spring) do this routinely.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文