Java – The final int parameter used in anonymous Runnable

The final int parameter used in anonymous Runnable… here is a solution to the problem.

The final int parameter used in anonymous Runnable

I was

wondering if I was using the correct method to call something in a different thread.
I did it on Android, but thought it was a general Java issue.

I have methods with some parameters. Suppose they are integers.

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);
      }
    });
  }

Now my question is, is it safe to use final int to create anonymous runnable without any class members? If I omit the final keyword for the x and y arguments, Eclipse reports an error. In my opinion, this is to use only constants in this case. If I pass a non-constant, is that okay? Will Java “keep” it constant by passing it to this function?

But I want to use JNI to call Test.callInMainThread from native. In my opinion, Java cannot tell if these numbers are constants or not. Can I trust Java to do some wonders? Will it always be like this?

I

thought maybe I have to create a proxy class, for example:

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();
}

The calling method will use:

  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);
      }
    });
  }

In this way, I can protect the value from garbage collection until runnable is used and discarded. Do I have to create a wrapper, or is it safe to mark final x in a method parameter? When I tried it, the final keyword worked just fine. But in threads, I don’t think whether it works now or not is the reason why it works forever. Does it always work with Final? If so, how was it made? Will there be a difference if the parameter is not a primitive type, but an object?

Update:
I already understand what final means in Java. That’s not the problem. The problem is where is the range of variables used when creating Runnable. They are local variables, which means that their values cannot be referenced after the function ends. Where are the values stored when the Runnable object is passed to other threads and waiting to execute?

Solution

Get a copy of parameters and local variables that reside on the method call stack inside the thread. This is because the thread still exists after the method call completes.

And requires the variable to

be final, forbidden to overwrite the original variable in the method, resulting in a different version in the thread. This is simply misleading. So it’s a problem to have two versions of the same name represent the same thing.

Well-thought-care language design.

(A slight simplification, not naming symmetry reversed, also holds.) )

Related Problems and Solutions