[英]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.