variable might already have been assigned when it

2019-02-21 18:02发布

research this code:

public class TestFinalAndCatch {
    private final int i;

    TestFinalAndCatch(String[] args) {
        try {
            i = method1();
        } catch (IOException ex) {
            i = 0;  // error: variable i might already have been assigned
        }
    }

    static int method1() throws IOException {
        return 1;
    }
}

compiler says that java: variable i might already have been assigned

But for me it is looks like impossible situation.

4条回答
Emotional °昔
2楼-- · 2019-02-21 18:32

i is final, so it can only be assigned once. The compiler is probably not smart enough to realize that if an exception is thrown, the first assignment won't take place, and if an exception isn't thrown, the second assignment won't take place.

查看更多
叛逆
3楼-- · 2019-02-21 18:35

The problem is that in this case compiler works syntax-based not semantic-based. There are 2 workarounds: First base on moving exception handle on method:

package com.java.se.stackoverflow;

public class TestFinalAndCatch {
    private final int i;

    TestFinalAndCatch(String[] args) {
        i = method1();
    }

    static int method1() {
        try {
            return 1;
        } catch (Exception ex) {
            return 0;
        }
    }
}

Second base on using temporar variable:

package com.java.se.stackoverflow;

import java.io.IOException;

public class TestFinalAndCatch {
    private final int i;

    TestFinalAndCatch(String[] args) {
        int tempI;
        try {
            tempI = method1();
        } catch (IOException ex) {
            tempI = 0;
        }
        i = tempI;
    }

    static int method1() throws IOException {
        return 1;
    }
}
查看更多
beautiful°
4楼-- · 2019-02-21 18:38

https://bugs.openjdk.java.net/browse/JDK-6326693?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel

Looks like JDK bug. And now status - Fixed. But I cannot find from which version.

查看更多
Lonely孤独者°
5楼-- · 2019-02-21 18:56

To overcome this problem, use a local variable in the try catch block and then assign that result to the instance variable.

public class TestFinalAndCatch {
    private final int i;

    TestFinalAndCatch(String[] args) {
        int tmp;
        try {
            tmp = method1();
        } catch (IOException ex) {
            tmp = 0;
        }
        i = tmp;
    }

    static int method1() throws IOException {
        return 1;
    }
}
查看更多
登录 后发表回答