我一直在仔细阅读JMapViewer的开源代码。如果有其他人希望查看它,请检查SVN。与匿名EventListener的JPanel - 为什么不GC摧毁监听器?
简而言之,主类是JMapViewer
,它是JPanel
的扩展。还有另外一个非常重要的课程,称为DefaultMapController
,它充当主要课程的MouseListener
。
我注意到的第一件奇怪的事情是,查看器没有对控制器的引用。该JMapViewer
构造函数实例化DefaultMapController
的匿名情况下,像这样:
public JMapViewer() {
// other stuff
new DefaultMapController(this);
}
在我看来这是一个糟糕的设计选择,因为该控制器具有万吨的方法(选项,切换等等 - 例如如下图所示) ,现在根本无法访问,所以它们有什么好处?
public void setMovementMouseButton(int movementMouseButton) {
// changes which mouse button is used to move the map
}
控制器确实具有给观看者的参考如上面的第一代码段,这是它如何能够实施控制。
然而,我想到了一些更奇怪的东西!如果这个匿名实例的监听器没有引用,为什么它甚至能够存活? GC不应该很快摧毁它吗?或者GC足够聪明地知道引用活动JComponent
的监听器类也必须保持活动才能正常工作,即使它因某种奇怪的原因而没有名称?
所以,两个真正的问题:
- 为什么GC不破坏对象?
- 这是一个糟糕的设计选择,还是有一些我不知道从实例化查看器的类访问控制器?
我想参与这个开放源码库,和我换一换的第一个想法是改变JMapViewer
类有一个字段引用它的控制器,并且改变构造函数,当前匿名控制器分配给此新领域。但是,我想确保我不会无知地错过什么。我已经搜索了整个代码库文本DefaultMapController
,并且它只出现在它自己的类定义中,以及JMapViewer
构造函数中的匿名实例化中。
编辑:
它似乎的确有访问匿名听众,通过使用java.awt.Component
方法getMouseListeners()
的方式。因此,在技术上,我可以在我的应用程序中搜索此集合中的DefaultMapController
实例,并使用它来访问我需要用来更改控制器选项的方法。如果我按照原来的想法去给它的控制器一个引用,现在我有一种循环引用(地图知道控制器和控制器知道地图)。这是一个坏主意吗?
为了方便起见,我添加了一个[tag:jmapviewer]标签,但我依照您的意见使用它。引用来源为+1。 – trashgod
@trashgod谢谢。我用'JMapViewer'替换了'JPanel'标签。 – The111