简体   繁体   English

线程:封闭范围中定义的局部变量必须是final或有效的final

[英]Threads: Local variable defined in an enclosing scope must be final or effectively final

I have my main class running in the main method. 我的主类在main方法中运行。 It runs a process that potentially takes a huge amount of time to complete, so I created another method to stop that process: it simply raises a flag that makes the whole process stop: 它运行的过程可能要花费大量时间才能完成,因此我创建了另一个方法来停止该过程:它只是引发一个使整个过程停止的标志:

public void stopResolutionProcess() {
    stop = true;
}

This is the call that executes the big process: 这是执行大型流程的调用:

boolean solutionFound = tournament.solve();

So right before it, I need to run a secondary thread to call stopResolutionProcess() : 因此,在此之前,我需要运行辅助线程来调用stopResolutionProcess()

Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Stop resolution process? (Y/N): ");
        String answer = sc.next();
        if (answer.equalsIgnoreCase("y")) {
            tournament.getSolver().stopResolutionProcess(); // error here
        }
    }
});

But I am getting an error in the last line. 但是我在最后一行遇到了错误。 It says: 它说:

Local variable tournament defined in an enclosing scope must be final or effectively final 封闭范围中定义的局部变量锦标赛必须是最终的或有效的最终

What approach should I take to solve this problem in order to test the method that stops the process? 为了测试停止过程的方法,我应该采取哪种方法来解决此问题?

So what is the problem.. a small example 那么问题是什么..一个小例子

String myString = new String("MyString");
Thread thr = new Thread() {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(myString);
        }
    }
}
thr.start();
myString = new String("AnotherString");

So what output would you expect here? 那么您在这里期望得到什么输出? Something like: 就像是:

MyString
MyString
AnotherString
AnotherString
AnotherString

The problem is that you don't know when the myString variable is changed. 问题是您不知道何时更改myString变量。 This could happen after it was printed 0 times, after being printed 5 times or any time in between. 打印0次后,打印5次后或之间的任何时间都可能发生这种情况。 Or in other words, this is not predictable and is very unlikely to be intended. 换句话说,这是无法预料的,​​并且极不可能实现。
In order to have a defined behaviour, the variable you use in the Thread needs to be final: 为了具有定义的行为,您在Thread中使用的变量必须是final:

final String myString = new String("MyString");
Thread thr = new Thread() {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(myString);
        }
    }
}
thr.start();
// now this following line is not valid anymore and will lead to a compile error
myString = new String("AnotherString");

Now we have a defined behaviour and we know that the output will be: 现在我们有了定义的行为,我们知道输出将是:

MyString
MyString
MyString
MyString
MyString

Your question itself has the answer to what you have asked. 您的问题本身可以回答您的问题。

Local variable tournament defined in an enclosing scope must be final or effectively final 封闭范围中定义的局部变量锦标赛必须是最终的或有效的最终

If anonymous class is created inside any method then all the local variables defined in the method but outside the body of the anonymous class should be made final in case they are needed to be used in anonymous class. 如果在任何方法内部都创建了匿名类,则该方法中定义的但在匿名类主体之外的所有局部变量都应设为最终变量,以防需要在匿名类中使用它们。

public class OuterClass{
    int x,y;
    public void someMethod(){

         final int neededByAnonymousClass = x + y + 30;

         Runnable runnable = new Runnable(){
              // This is like we are creating a class which simply implements Runnable interface.
              // Scope of this class is inside the method someMethod()
              // run() method may be executed sometime later after the execution of someMethod() has completed.
             // all the local variables needs to be final in order they can be used later in time when run() gets executed.

             public void run(){
                 System.out.println(neededByAnonymousClass+ 40);
             }
         }
         Thread thread = new Thread(runnable); // passing the object of anonymous class, created above
         thread.start();
    }
}

So just make your all the local variables (defiend inside the scope of a method) as final which you wish to use inside the run() method of your local anonymous class (class without name) . 因此,只需将您希望在本地匿名类(无名称类)的run()方法中使用的所有局部变量(在方法范围内进行限定)作为最终变量即可 In case you wish to modify the value of a variable then do modifications first and then create the anonymous class. 如果您希望修改变量的值,请先进行修改,然后再创建匿名类。 Create another final variable and initialize it with the modified value and use the same in the anonymous class. 创建另一个最终变量,并使用修改后的值对其进行初始化,然后在匿名类中使用该变量。

I quote below from answer of another related question : Local variable needs to be declared final 我在下面引用另一个相关问题的答案: 局部变量需要声明为final

It's a promise to yourself (and to the compiler) that the value of box won't change in the enclosing scope. 对您自己(和对编译器)的承诺是,box的值在封闭范围内不会改变。 The compiler will tell you if you break that promise. 编译器会告诉您是否违反了承诺。

The variable value will be used some time later after the execution of the method is completed. 该方法的执行完成后,将在一段时间后使用变量值。 Hence local variables must be declared as final. 因此,必须将局部变量声明为final。 The methods in the anonymous object are not executed in order they are written (sequentially) 匿名对象中的方法未按顺序写入(依次)执行

Suppose below lines of code where we have a method : methodA() and it contains definition of an anonymous class. 假设下面的代码行中有一个方法:methodA(),它包含一个匿名类的定义。

[ line-1 : method A, line-2 method A, line-3 : anonymous class , Line 4 method of anonymous class, line 5 method A ] ==> Order of execution [第1行:方法A,第2行方法A,第3行:匿名类,匿名类的第4行方法,第5行方法A] ==>执行顺序

Line 1, Line 2, Line 3 (just the object creation of the anonymous class), Line 5. Line 4 will be executed later when method on the object created of anonymous class is invoked. 第1行,第2行,第3行(仅创建匿名类的对象),第5行。稍后将调用对匿名类创建的对象的方法时执行第4行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在封闭作用域中定义的局部变量必须是最终的或有效的最终变量 - Local variable defined in an enclosing scope must be final or effectively final 在封闭 scope 中定义的局部变量迭代必须是最终的或有效的最终 - local variable iteration defined in an enclosing scope must be final or effectively final 在封闭 scope 中定义的局部变量 ObjList 必须是最终的或有效的最终 - Local variable ObjList defined in an enclosing scope must be final or effectively final 在封闭范围内定义的局部变量 log 必须是 final 或有效 final - Local variable log defined in an enclosing scope must be final or effectively final 我在封闭作用域中定义的局部变量必须是最终的或有效的最终变量 - Local variable i defined in an enclosing scope must be final or effectively final 在封闭的 scope 中定义的局部变量 collect 必须是最终的或有效的最终的 - Local variable collect defined in an enclosing scope must be final or effectively final 封闭范围中定义的局部变量textfeild_1必须是final还是有效的final? - local variable textfeild_1 defined in an enclosing scope must be final or effectively final? 计时器错误的int值:在封闭范围内定义的局部变量ans必须是final或有效的final - int for timer error: Local variable ans defined in an enclosing scope must be final or effectively final 在封闭范围内定义的局部变量 statusMessage 在返回新对象时必须是最终的或有效的最终 - Local variable statusMessage defined in an enclosing scope must be final or effectively final on returning a new object Java 8 显示此错误。 在封闭作用域中定义的局部变量 itemList 必须是 final 或有效 final - Java 8 shows this error. Local variable itemList defined in an enclosing scope must be final or effectively final
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM