local variables referenced from an inner class must be final or effectively final

37,300

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: ");
Share:
37,300
Bails
Author by

Bails

Updated on July 09, 2022

Comments

  • Bails
    Bails almost 2 years

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

    }

  • Bails
    Bails over 8 years
    Thanks so much for the help, that did the trick. I figured it was something tiny that had to be adjusted.
  • Vivek Gupta
    Vivek Gupta over 3 years
    Just curious, What if those variables (hi and lo) were repeatedly updated?. How can we solve such problem.
  • Andreas
    Andreas over 3 years
    @VivekGupta Huh? They are repeatedly updated in the code that follows.
  • Meeth
    Meeth almost 2 years
    How would I approach this if I needed high and low outside of run() but inside HiLo()?