大家晚上好
当尝试将一个对象传递给另一个对象构造函数时,我似乎遇到了一个奇怪的问题,该对象构造函数也依赖于它所传递到的对象。
例如下面的例子:
ToolBar myToolBar = new ToolBar(webPanel);
WebPanel webPanel = new WebPanel(myToolBar);
但是,在构造 ToolBar 时,它会返回 NullPointerException。当然,这是因为 webPanel 还没有构建,它需要它。
减速和初始化都必须保留在同一个类(称为 BuildUI)中,因为这是我设置属性的地方。 (工具栏创建 webPanel 对象也是没有意义的,反之亦然)。
我也不确定这是否是好的编程实践,因为两个对象都需要相互引用。
非常感谢这里的任何建议。谢谢,汤姆。
这会导致你所看到的问题。您可以使用 setter-getter 方法来代替这种方法,在该方法中使用默认构造函数构造对象,例如
ToolBar myToolBar = new ToolBar();
WebPanel webPanel = new WebPanel();
然后使用setter方法设置完全构造对象所需的实例变量。
myToolBar.setWebPanel(webPanel);
webPanel.setToolBar(myToolBar);
这似乎是恶性循环的一个很好的例子。
我建议使用单独的方法来打破这个循环,例如
addToolbar()
,将另一个对象添加到其中一个类,而不是构造函数。如果尚未调用该方法,您只需要添加一些检查以避免非法对象状态:
class WebPanel {
public void addToolbar(Toolbar toolbar) {
...
}
}
...
class ToolBar {
public ToolBar(WebPanel parent) {
...
}
}
...
WebPanel webpanel = new WebPanel();
webpanel.addToolbar(new Toolbar(webpanel));
一般来说,“子”对象最好将父对象作为构造函数参数,然后通过方法调用添加到父对象,而不是相反。在 UI 中,外部元素是其内容的父元素 - 在你的情况下,我可能期望
WebPanel
包含 - 从而成为 - ToolBar
对象的父元素...
我之前已经让对象互相引用了。 IE。在游戏中,对象可能包含对其单元格的引用,并且单元格可以包含对该对象的引用。
您只需要小心创建对象的方式即可。
没有说它们必须都传递到彼此的构造函数中,事实上,您可以创建这两个对象,然后在不同的方法中,让它们互相引用。
在使用值之前检查它是否为空也不是一种不常见的做法(但只有在该值实际上有理由为空时才这样做。)
嗯..您可以做的是创建一个围绕工具栏和 WebPanel 的模型对象。
public class SomeModel{
WebPanel panel;
Toolbar toolbar;
}
或者您可以创建工具栏对象..并在工具栏的构造函数中创建您的网页面板
public WebPanel()
{
this.toolbar= new Toolbar(this);
}
webPanel = new WebPanel();
webPanel.getToolbar() ;
好吧,这是作弊 lmao 这取决于一个对象是否是另一个对象的复合对象;虽然我认为模型方式更好..没有循环引用。
也许你先声明一下
WebPanel webPanel = new WebPanel(myToolBar);
然后
ToolBar myToolBar = new ToolBar(webPanel);
对象必须先存在才能传递。
有多种方法可以实现;我通常更喜欢将参数传递给两者之一,并让它调用另一个中的
setter
方法:
class ToolBar {
void setWebPanel(WebPanel wp) {
_wp = wp;
}
....
}
class WebPanel {
WebPanel(ToolBar t) {
_t = t;
_t.setWebPanel(this);
}
}
ToolBar myToolBar = new ToolBar(webPanel);
WebPanel webPanel = new WebPanel(myToolBar);
new Toolbar()
而不是new Toolbar(webPanel)
然后在
WebPanel(Toolbar toolbar)
构造函数中执行 toolbar.add(this)
其中 add(WebPanel webPanel)
方法在 Toolbar
中定义。