0

My compiler is warning me that that an instance variable, a 2d int[][] array, might not have been initialised when I go to assign it.

I understand why the compiler might think that, because it is initialised in a double if statement. However the first if is on a boolean that is initialised to true, and the second if throws an exception on the else. I am confident of the logic of the program but the compiler obviously is not.

Does anyone have any tips for overcoming this kind of problem? I don't want to otherwise initialise the variable because it is meant to be final.

The variable of concern is the board variable. The below is part of a constructor for the object which contains the variable.

    try {
        FileReader fr = new FileReader(filename);
        BufferedReader br = new BufferedReader(fr);
        boolean first = true;
        int lineCount = 0;
        String line;

        while ((line = br.readLine()) != null) {
            String lineParts[] = line.split(" ");
            if (first) {
                if (lineParts.length == 2) {
                    this.xSize = Integer.parseInt(lineParts[0]);
                    this.ySize = Integer.parseInt(lineParts[1]);
                    board = new int[this.ySize][this.xSize];
                    first = false;
                } else { throw new RuntimeException(); }
            } else {
                lineCount++;
                if (lineParts.length == this.xSize) {
                    for (int i = 0; i < this.xSize; i++) {
                        board[lineCount][i] = Integer.parseInt(lineParts[i]);
                    }
                } else throw new RuntimeException();
            }
        }
        br.close();
        if (lineCount != this.ySize) throw new RuntimeException();


    } 
7
  • 2
    Show us your code! Commented Apr 7, 2017 at 11:58
  • Hi, added the code Commented Apr 7, 2017 at 12:01
  • 1
    So what happens if the file doesn't have any lines? Remember that the compiler only does basic static analysis. Commented Apr 7, 2017 at 12:05
  • 1
    If it doesn't have any lines the while loop won't start Commented Apr 7, 2017 at 12:07
  • 2
    If the field is final, the compiler expects that this variable is initialized on all paths along your code. If there is even one path that doesn't initialize, it will complain Commented Apr 7, 2017 at 12:08

1 Answer 1

1

Indeed, the compiler can't unravel the loop logic enough to know the final variable is initialized before use.

You'll need to move handling of the first line out of the loop — which is reasonable anyway, since the content of the loop is almost completely different for the first line and subsequent lines:

try {
    FileReader fr = new FileReader(filename);
    BufferedReader br = new BufferedReader(fr);
    int lineCount = 0;
    String line;

    line = br.readLine();
    if (line != null) {
        String lineParts[] = line.split(" ");
        if (lineParts.length == 2) {
            this.xSize = Integer.parseInt(lineParts[0]);
            this.ySize = Integer.parseInt(lineParts[1]);
            board = new int[this.ySize][this.xSize];
        } else {
            throw new RuntimeException();
        }
        while ((line = br.readLine()) != null) {
            String lineParts[] = line.split(" ");
            lineCount++;
            if (lineParts.length == this.xSize) {
                for (int i = 0; i < this.xSize; i++) {
                    board[lineCount][i] = Integer.parseInt(lineParts[i]);
                }
            } else {
                throw new RuntimeException();
            }
        }
    }
    br.close();
    if (lineCount != this.ySize) throw new RuntimeException();
} 

Note: This code preserves the previous code's behavior that it doesn't count the first line. I'm guessing the fact it's special includes not counting it. :-)


Side note: I'd strongly recommend using try-with-resources in that code, not only for best practices, but because you're not closing the file when you throw your exceptions:

try (
    FileReader fr = new FileReader(filename);
    BufferedReader br = new BufferedReader(fr);
) {
    int lineCount = 0;
    String line;

    line = br.readLine();
    if (line != null) {
        String lineParts[] = line.split(" ");
        if (lineParts.length == 2) {
            this.xSize = Integer.parseInt(lineParts[0]);
            this.ySize = Integer.parseInt(lineParts[1]);
            board = new int[this.ySize][this.xSize];
        } else {
            throw new RuntimeException();
        }
        while ((line = br.readLine()) != null) {
            String lineParts[] = line.split(" ");
            lineCount++;
            if (lineParts.length == this.xSize) {
                for (int i = 0; i < this.xSize; i++) {
                    board[lineCount][i] = Integer.parseInt(lineParts[i]);
                }
            } else {
                throw new RuntimeException();
            }
        }
    }
    if (lineCount != this.ySize) throw new RuntimeException();
} 
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks TJ Crowder! Also learnt about not mixing content in your loops. And you're right the first line doesn't count, it will just contain size information for the 2d board.
@edd91: Glad that helped. I added a second part about try-with-resources just now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.