1. ホーム
  2. java

[解決済み】内部クラスから参照されるローカル変数はfinalかeffective finalでなければならない

2022-02-07 23:36:16

質問

このプログラムは私のクラスの最終課題なのですが、なぜ「内部クラスから参照されるローカル変数は final または effectively final" でなければならない」というエラーが発生するのか、その原因がわかりません。このプログラムは、#の配列を並べ替えて、その配列の最大値と最小値を見つけるために並行スレッドを実行しています。同時実行なしで作成したときは、このエラーは発生しませんでした。highとlowの変数をどこで確定させるか悩んでいます。

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

これは、エラーを発生させるコードのブロックです。int high = numbers[0]; または int low = numbers[0]; のどちらかを final にすると、その値を final にできないというエラーが発生し、反対側の変数に対するエラーは消えます。

以下はプログラムの残りです。何か手助けがあれば、よろしくお願いします。

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

}

解決方法は?

の両方を更新し続ける。 highlow の内側で run() メソッドで定義されているため、事実上ファイナルではありません。

の外では必要ないので run() メソッドの中に移動してください。

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: ");