仅当调用 System.out.println 时才会调用 Java 重写方法

标签 java overriding mouselistener

以下是我创建的对象的两种方法。父类(super class)已实现 MouseListener。

@Override public void mousePressed(MouseEvent event){
    mIsPushed = true;
    System.out.println("Button pushed");
  }

  @Override public void mouseReleased(MouseEvent event){
    mIsPushed = false;
    System.out.println("Button released");
  }

当两个 System.out.println 调用取消注释时,程序可以正常工作并按其应有的方式运行。当它们不存在时,它什么也不做。我什至在 mIsPushed 赋值处放置了断点,但从未到达它们。

但是,如果我在调用这两个函数的地方放置一个断点,调试器就会到达它并进行调用。

谁能告诉我我错过了什么?

最佳答案

这可能是由于不同的线程缓存了自己的 mIsPushed 变量值。

您需要同步对此变量的访问。您有几种不同的选择:

  • 将其声明为 volatile
  • 使用 java.util.concurrent 包中的一些高级构造(例如 AtomicBoolean)
  • 使用 synchronized 关键字同步对变量的访问。

更详细地说:Java 内存模型不保证从一个线程读取变量会产生从另一个线程写入该变量的最后一个值。这是为了允许 JVM 优化 Java 程序的执行。添加 System.out.println 可能会刷新缓存并导致在需要时加载新值。

要明确告诉 JVM 确保不应该使用缓存值,您需要在写入和读取之间引入“发生之前”关系。

进一步阅读:

关于仅当调用 System.out.println 时才会调用 Java 重写方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8040821/

相关文章:

swift - 覆盖作为 Obj-C 框架类一部分的 swift 函数

java - JSpinner 对 Windows 上的 MouseWheelEvent 没有反应

java - 将 MouseListener 与 vlcj 一起使用

java - JOptionPane 无限循环

java - 将字节数组转换为 double 组

java - .tailSet 据说返回 NavigableSet,但似乎返回 TreeSet

scala - 覆盖类型边界时出现不兼容的类型错误

C#:有什么方法可以跳过多态性中的一个基本调用?

java - 在抽象类中执行方法执行顺序

java - Java中如何获取被用户环境变量覆盖的系统环境变量?