EDT 违规是否有可能在外部软件中导致 NullPointerException?
我有一个 Java 软件,最近集成到另一个 Java 软件(我将其称为“外部”软件)中。我们使用监听器和回调机制来实现两个软件之间的“通信”。
“外部”软件的创建者表示,由于我的代码中存在一些 EDT 违规,他们得到了 NullPointerException。可以这样吗?
I have a Java software that was recently integrated into another Java software (which I will call "external" software). We use listeners and call back mechanisms for "communication" between two softwares.
Creators of the "external" software say that they get a NullPointerException because of some EDT violations in my code. Can it be the case?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果这些组件以某种方式与 Swing 组件交互(假设它们作为侦听器附加到组件上),那么 EDT 违规当然可能导致类似的行为。当然,您可以反驳他们,询问他们是否对这些方法有断言,如果您启用断言,代码将清楚地显示哪里违反了 EDT 规则。
编辑(回应评论):
EDT 的基本经验法则是,无论何时启动新线程,都不要接触任何 Swing 组件(或任何接触 Swing 组件的东西,例如模型),而不将该代码包装在可运行并调用 SwingUtilities.invokeLater(Runnable)。这需要纪律和一些额外的设计工作,但在任何严肃的应用程序中绝对是必要的。
如果您在同步行为(例如弹出对话框并等待答案)上投入了大量资金,您可以调用 SwingUtilities.invokeAndWait(Runnable),但您应该尽量避免这样做。另外,请确保在 EDT 上不在时调用该方法,否则该方法将不起作用。
开始控制此类代码的一种方法是使用如下断言:
只要您有涉及 GUI 的代码并在启用断言的情况下运行。这样,您将看到错误地接触 Swing 组件的确切代码路径。
EDT violations certainly can cause behavior like this, provided these components interact with Swing components in some way (say they are attached as listeners on components). Of course, you could turn the tables on them and ask them if they have assertions on these methods and that if you enable assertions will the code clearly show where the EDT rule is violated.
Edit (in response to comment):
The basic rule of thumb with the EDT is that whenever you start a new thread do not touch any Swing component (or anything that touches a Swing component, such as a Model) without wrapping that code in a Runnable and calling SwingUtilities.invokeLater(Runnable). It takes dicipline and some extra design effort, but it is definitely necessary in any serious application.
If you have a serious amount invested in syncronous behavior (such as poping up a dialog and waiting for an answer) you can call SwingUtilities.invokeAndWait(Runnable), but you should try to avoid the need for that as much as possible. Also, make sure you call that method while not on the EDT, it doesn't work otherwise.
One way to start getting such code under control is to use asserts like this:
whereever you have code that touches the GUI and run with asserts enabled. That way you will see exact code paths that are touching Swing components incorrectly.