2

情况:主窗体调用带有文本框的模态jDialog,其中用户填写参数以创建或修改某个类的实例,称为ClassA。

当对话框需要修改现有实例时,它作为参数传入构造函数。否则 jDialog 将创建一个新的 ClassA 实例。

问题:主窗体需要访问那个新实例,我认为将整个主窗体作为参数传递,并让对话框通过方法调用将新实例推入其中是不干净的代码,因为这样可以完美地重新可用的独立对话框仅可用于需要特定类名和方法来接收新实例的单个主窗体。

在单击 OK 按钮后,通过调用 getClassAInstance() 方法(在修改现有实例时也可以调用该方法),使主窗体从 jdialog 获取新实例更为合乎逻辑。该方法在相关 jdialog 的新实例上的“setVisible(true)”方法之后调用。对话框出现,主窗体的线程会一直休眠,直到对话框关闭(因为它是模态的)。OK 按钮调用 jDialog 的 dispose() 方法,然后下一条语句是主窗体对 jDialog 的 getClassAInstance() 调用。

这是代码中的相同内容..

ClassAInstanceMakerDialog imd = new ClassAInstanceMakerDialog(this, true);
imd.setVisible(true);
//imd.dispose(); after OK button click
System.out.println(imd.getClassAInstance()); //return a new ClassA instance

//output: whatever ClassA.toString() should return, works fine

问题:我试过了,它似乎工作得很好。但是,这是一个好的代码吗?getClassAInstance() 方法返回“null”是否有任何危险,因为垃圾收集器在处理 jDialog 之后并且在主窗体完成调用之前收集了 ClassA 实例?

如果我没有说清楚,请原谅我,我不是以英语为母语的人。如果您想看一些代码,请告诉我...

4

3 回答 3

2

我认为访问保存 ClassA 实例的对话框实例的成员变量是完全合法的,对话框实例在超出范围之前不会被垃圾收集,而不仅仅是因为你调用了 dispose 。

我会稍微偏爱一个解决方案,在该解决方案中定义一个带有签名的事件处理程序接口

someThingHappened(ClassA toThisObject),使您的主窗体或任何可能感兴趣的 ClassA 事物实现该接口,从而可以在对话框可见之前将侦听器添加到对话框。

这样,您将稍微放松对话框和主窗体之间的耦合。

于 2012-04-07T18:09:32.580 回答
1

我认为这不会dispose()为垃圾收集设置 JDialog,而只是释放资源。该对话框仍然可以根据Window API重复使用(因为 JDialog 从 Window 继承了此方法):

释放此 Window、其子组件及其所有子组件使用的所有本机屏幕资源。也就是说,这些组件的资源将被销毁,它们消耗的任何内存都将返回给操作系统,并且它们将被标记为不可显示。

通过随后调用 pack 或 show 重建本机资源,可以使 Window 及其子组件再次可显示。重新创建的 Window 及其子组件的状态将与这些对象在 Window 被释放时的状态相同(不考虑这些操作之间的其他修改)。

注意:当 Java 虚拟机 (VM) 中的最后一个可显示窗口被处理掉时,VM 可能会终止。有关详细信息,请参阅 AWT 线程问题。

只要仍然存在对 JDialog 对象的有效可达引用,它就不会被垃圾回收。我认为处理对话框的成本是您的代码将需要花费(非常)一点时间来重新创建资源。

于 2012-04-07T18:06:44.887 回答
1

IDisposable拥有一个可以在Dispose调用之后使用的包含属性或方法来返回有关在调用之前发生的事情的信息是完全合理和适当的Dispose。与其盲目地强制规定已处置对象的任何和所有方法都应抛出ObjectDisposedException,不如考虑哪些方法和属性对已处置对象有意义或没有意义。尝试访问已处置的对象应ObjectDisposedException 优先于重新获取已释放的资源或逃避由于处置而发生的其他一些异常。如果方法或属性访问可以在没有任何释放资源的情况下成功,则通常应该允许这样做。

于 2012-05-08T22:45:06.320 回答