This program is the final assignment for my class and I'm have issues figuring out why I'm receiving the error "local variables referenced from an inner class must be final or effectively final". The program is running concurrent threads to sort an array of #'s and then find the high and low values of that array. When I created it without the concurrency, I didn't have this error. I'm struggling as to where to finalize the high and low variable.
public void HiLo(int[] numbers){
int high = numbers[0];
int low = numbers[0];
Runnable r2 = new Runnable(){
@Override
public void run() {
System.out.println("The highest value is: ");
for (int index = 1; index < numbers.length; index++){
if (numbers[index] > high)
high = numbers[index];
System.out.println(high);
}
System.out.println();
System.out.println("The lowest value is: ");
for (int ind = 1; ind < numbers.length; ind++){
if (numbers[ind] < low)
low = numbers[ind];
System.out.println(low);
}
}
};
pool.execute(r2);
}
This is the block of code producing the error. If I make either the int high = numbers[0]; or int low = numbers[0]; final then I get an error that I can't make that value final and the error for the opposite variable disappears.
Here is the rest of the program. Any help is appreciated.
package concurrentthread;
import java.util.Arrays;
import java.util.Scanner;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class ConcurrentThread {
static Executor pool = Executors.newFixedThreadPool(2);
public static void main(String[] args) {
int size;
Scanner keyboard = new Scanner(System.in);
ConcurrentThread sort = new ConcurrentThread();
ConcurrentThread hilo = new ConcurrentThread();
System.out.println("This program will calculate the highest and lowest "
+ "numbers entered by the user \nand also sort them in "
+ "ascending order");
System.out.println();
System.out.print("How many numbers would you like in the array? ");
size = keyboard.nextInt();
final int[] numbers = new int[size];
for (int index = 0; index < numbers.length; index++){
System.out.print("Please enter a number between 1 and 100: ");
numbers[index] = keyboard.nextInt();
}
System.out.println();
sort.Sort(numbers);
hilo.HiLo(numbers);
//System.exit(0);
}
public void Sort(int[] numbers){
int sort = numbers[0];
Runnable r1 = () -> {
Arrays.sort(numbers);
System.out.println("The sorted values are: ");
for (int index = 0; index < numbers.length; index++)
System.out.print(numbers[index] + " ");
System.out.println();
};
pool.execute(r1);
}
public void HiLo(int[] numbers){
final int high = numbers[0];
int low = numbers[0];
Runnable r2 = new Runnable(){
@Override
public void run() {
System.out.println("The highest value is: ");
for (int index = 1; index < numbers.length; index++){
if (numbers[index] > high)
high = numbers[index];
System.out.println(high);
}
System.out.println();
System.out.println("The lowest value is: ");
for (int ind = 1; ind < numbers.length; ind++){
if (numbers[ind] < low)
low = numbers[ind];
System.out.println(low);
}
}
};
pool.execute(r2);
}
}
Like methods, local variables and parameters need not to be declared final.
You can declare the variable final, or make it an instance (or global) variable. If you declare it final, you won't be able to change it later. Any variable defined in a method and accessed by an anonymous inner class must be final.
A local inner class cannot be instantiated from outside the block where it is created in. Till JDK 7, the Local inner class can access only the final local variable of the enclosing block. However, From JDK 8, it is possible to access the non-final local variable of enclosing block in the local inner class.
final is the only allowed access modifier for local variables. final local variable is not required to be initialized during declaration. final local variable allows compiler to generate an optimized code. final local variable can be used by anonymous inner class or in anonymous methods.
You keep updating both high
and low
inside the run()
method, making them by definition not effectively final.
Since you don't need them outside the run()
method anyway, just move the two lines inside.
public void HiLo(int[] numbers){
Runnable r2 = new Runnable(){
@Override
public void run() {
int high = numbers[0];
int low = numbers[0];
System.out.println("The highest value is: ");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With