Java – Final fields and anonymous classes

I'm still not satisfied with the explanation of anonymous class and final field There are many questions trying to explain the obvious, but I can't find the answers to all the questions: -)

Assume the following code:

public void method(final int i,int j) {
    final int z = 6;
    final int x = j;
    int k = 5;
    new Runnable() {
        public void run() {
            System.out.print(i);
            System.out.print(x);
            System.out.print(z);
            System.out.print(k);
        }
    };
}

>This code cannot be compiled due to the "incomplete" K attribute. > I understand that the compiler can replace Z attributes with declared values during compilation

When I searched for a solution, X and I found that the answer said:

If they are parameters of a method, how does it apply to fields I and X? Don't know them during compilation? This method is applicable to Z

On the other hand, there is an explanation of stack issues:

I will understand that the anonymous class somehow copies all the necessary contents (fields) during the creation process The lack of final has obvious problems. If some of the code below the anonymous class declaration will change the value, the execution will use possible stale values

However, this can solve the problem when anonymous class' methods are executed outside the scope of the properties used

But this method should work even without a final declaration, because it only copies all fields

Both methods are independent to me Speaking of which - it can solve my problem - I haven't found the field of the final method of work Even if the methods are completed, they will not be removed from the stack? It seems nonsense to me, but it will explain a lot of things: -)

What is the correct answer?

Solution

In my opinion, you are confused between a variable declared final and its being a constant

The compiler does not replace all references to local variables with constants - but when constructing an instance of an anonymous class, the current value of each related variable is passed to the constructor and stored in a variable in the anonymous class This is as good for parameters as any other type of local variable

So this Code:

public static void method(final int x) {
    Runnable r = new Runnable() {
        @Override public void run() {
            System.out.println(x);
        }
    };
    r.run();
}

Roughly equivalent to:

public static void method(final int x) {
    Runnable r = new AnonymousRunnable(x);
    r.run();
}

private static class AnonymousRunnable implements Runnable {
    private final int x;

    AnonymousRunnable(int x) {
        this.x = x;
    }

    @Override public void run() {
        System.out.println(x);
    }
}

I've set both methods and nested classes static to avoid worrying about whether this is caught

When capturing local variables, they must be final to avoid possible confusion Assuming this is not the case – consider the following example:

void method() {
    int x = 10;
    Runnable r = new Runnable() {
        @Override public void run() {
            System.out.println(x);
        }
    };
    x = 20;
    r.run(); // Should this print 10 or 20?
}

Use the current working mode of anonymous class, but only remove the final limit, it will print 10... But developers may want it to print 20 Again, you should consider what happens if you modify X in the run method (as Joop said in his answer, in Java 8, captured local variables are "valid final" – so they behave as if you had declared them final, but did not explicitly do so.)

As an example of a different approach, c# handles closures in different ways (for anonymous functions) and promotes local variables to an anonymous class so that they can be modified This is a more complex method, but a little more flexible You may find my article about closures in Java and C # useful

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>