java - 匿名 Runnable 中使用的最终 int 参数

标签 java android final runnable

我想知道我是否使用正确的方法在不同的线程中调用某些东西。 我是在 Android 上做的,但认为这是一般的 Java 问题。

我有一些参数的方法。假设它们是整数。

class Main1 {
  public static void mainOnlyWork(int x, int y) {
     // not important here.
  }
}

class Test {
  Handler mHandler;

  // called from main thread, stored as reference.
  public Test() {
    mHandler = new Handler();
  }

  public static void callInMainThread(final int x, final int y) {
    mHandler.post(new Runnable() {
      public void run() {
        Main1.mainOnlyWork(x, y);
      }
    });
  }

现在我的问题是,使用 final int 来创建没有任何类成员的匿名 runnable 是否安全?如果我省略 x 和 y 参数的 final 关键字,Eclipse 会报错。在我看来,这是为了在这种情况下只使用常量。如果我传递的不是常数,可以吗? Java 会通过传递给这个函数来“使”它保持常量吗?

但我想使用 JNI 从 native 调用 Test.callInMainThread。在我看来,Java 无法判断这些数字是否为常量。我可以相信 Java 会创造一些奇迹吗?它会一直这样吗?

我想也许我必须创建代理类,例如:

private abstract RunnableXY implements Runnable {
  public RunnableXY(int x, int y) {
    this.x = x;
    this.y = y;
  }

  public int x;
  public int y;

  public abstract void run();
}

调用方法将使用:

  public static void callInMainThread(final int x, final int y) {
    mHandler.post(new RunnableXY(x,y) {
      public void run() {
        Main1.mainOnlyWork(this.x, this.y);
      }
    });
  }

通过这种方式,我可以保护值免受垃圾收集,直到使用并丢弃 runnable。我是否必须创建包装器,或者在方法参数中标记 final x 是否安全?当我尝试时,final 关键字工作得很好。但是在线程中,我不认为它现在是否有效是它永远有效的原因。它总是与 final 一起工作吗?如果有的话是怎么做出来的?如果参数不是原始类型,而是对象,会有区别吗?

更新: 我已经了解 final 在 Java 中的含义。这不是问题所在。问题点是在创建 Runnable 时使用的变量范围在哪里。它们是局部变量,这意味着在函数结束后无法引用它们的值。当 Runnable 对象被传递给其他线程并等待执行时,这些值存储在哪里?

最佳答案

在线程内部获取参数和局部变量(驻留在方法调用堆栈上)的副本。这是因为在方法调用完成后,线程仍然存在。

并且要求变量是final的,禁止在方法中覆盖原来的变量,导致线程中有不同的版本。这简直是​​误导。因此,让同名的两个版本表示同一事物是一个问题。

精心的语言设计。

(稍微简化,不命名对称颠倒的情况,同样成立。)

关于java - 匿名 Runnable 中使用的最终 int 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17812498/

相关文章:

Java代码静态Final变量的使用

java - Android 中如何将手写笔记转换为文本笔记?

java - Hibernate 验证整数的数字大小

android - 在 Android 中向用户显示提示的新样式

安卓指纹扫描仪应用程序

android - 如何使Android View 宽度=(父宽度 - 一些常数)

java - 为什么模板方法被标记为final?

使用 Jersey 的 Java Async REST Web 服务?

java - 使用 Java 执行 Postman 集合

java - 最终变量的理解