可能已经分配了常量变量

时间:2015-07-08 23:12:56

标签: java exception

我真的需要帮助。不知道如何解决这个问题。我想从属性文件中加载一些常量。我认为,Catch with FileNotFoundException 只能在 properties.load()上抛出。但是IDE说那个

VK_MIN_ID = VK_MIN_ID_DEFAULT;
VK_MAX_ID = VK_MAX_ID_DEFAULT;
MAX_USERS_TO_PARSE_AT_ONCE = MAX_USERS_TO_PARSE_AT_ONCE_DEFAULT;

可能已经分配了这些变量。哪里? 完整代码:

private static final int VK_MIN_ID;
private static final int VK_MIN_ID_DEFAULT = 1;
private static final int VK_MAX_ID;
private static final int VK_MAX_ID_DEFAULT = 999_999_999;
private static final int MAX_USERS_TO_PARSE_AT_ONCE;
private static final int MAX_USERS_TO_PARSE_AT_ONCE_DEFAULT = 500;

static {
    FileInputStream fileInputStream;
    Properties properties = new Properties();

    try {
        fileInputStream = new FileInputStream("src/main/resources/vk.properties");
        properties.load(fileInputStream);

        if (properties.containsKey("vk.min.id")) {
            VK_MIN_ID = Integer.parseInt(properties.getProperty("vk.min.id"));
        } else {
            VK_MIN_ID = VK_MIN_ID_DEFAULT;
        }
        if (properties.containsKey("vk.max.id")) {
            VK_MAX_ID = Integer.parseInt(properties.getProperty("vk.max.id"));
        } else {
            VK_MAX_ID = VK_MAX_ID_DEFAULT;
        }
        if (properties.containsKey("max.users.to.parse.at.once")) {
            MAX_USERS_TO_PARSE_AT_ONCE = Integer.parseInt(properties.getProperty("max.users.to.parse.at.once"));
        } else {
            MAX_USERS_TO_PARSE_AT_ONCE = MAX_USERS_TO_PARSE_AT_ONCE_DEFAULT;
        }
    } catch (FileNotFoundException e) {
        logger.warn("Файл свойств отсуствует! Устанавливаем настройки по умолчанию...");
        VK_MIN_ID = VK_MIN_ID_DEFAULT;
        VK_MAX_ID = VK_MAX_ID_DEFAULT;
        MAX_USERS_TO_PARSE_AT_ONCE = MAX_USERS_TO_PARSE_AT_ONCE_DEFAULT;
    } catch (IOException e) {
        logger.error("Ошибка чтения файла свойств! Работа будет прекращена", e);
    }
}

非常感谢。

3 个答案:

答案 0 :(得分:3)

Java编译器没有看到我们可以看到的内容 - MAX_USERS_TO_PARSE_AT_ONCE的赋值位于try块的末尾,因此它被分配到那里或在catch阻止。它看到它可能会在try块中分配,抛出异常,并在catch块中再次分配。

使用临时变量解决此问题。

int temp;
try {
    // other code
    if (properties.containsKey("max.users.to.parse.at.once")) {
        temp = Integer.parseInt(properties.getProperty("max.users.to.parse.at.once"));
    } else {
        temp = MAX_USERS_TO_PARSE_AT_ONCE_DEFAULT;
    }
} catch (FileNotFoundException e) {
    // other code.
    temp = MAX_USERS_TO_PARSE_AT_ONCE_DEFAULT;
} catch (IOException e) {
    // You'll need to assign something to temp here too.
}

在上一个catch阻止后,将temp分配给您的final变量一次。

MAX_USERS_TO_PARSE_AT_ONCE = temp;

这样您就可以保留MAX_USERS_TO_PARSE_AT_ONCE final

答案 1 :(得分:2)

您可以使用简单try-catch替换所有内容,而不是拥有catch block并在if-else中设置值,而无需删除{{} 1}}。像这样:

final

修改

您无法从File f = new File("src/main/resources/vk.properties"); if (f.exists()) { // set values here from FileInputStream // ... } else { // set alternate values here if the file is not found. VK_MIN_ID = VK_MIN_ID_DEFAULT; VK_MAX_ID = VK_MAX_ID_DEFAULT; MAX_USERS_TO_PARSE_AT_ONCE = MAX_USERS_TO_PARSE_AT_ONCE_DEFAULT; } 块分配常量的原因是,即使 知道异常将是在第一次设置值之前捕获, 编译器 对于事实并不知道。它必须假设异常可以在catch块中的任何位置抛出。因此,从编译器的角度来看,可以在捕获异常之前设置最终变量,因此它会给出错误。

答案 2 :(得分:1)

问题在于:

    VK_MIN_ID = VK_MIN_ID_DEFAULT;
    VK_MAX_ID = VK_MAX_ID_DEFAULT;
    MAX_USERS_TO_PARSE_AT_ONCE = MAX_USERS_TO_PARSE_AT_ONCE_DEFAULT;

VK_MIN_IDVK_MAX_IDMAX_USERS_TO_PARSE_AT_ONCE被声明为final,这意味着一旦分配,您就无法更改其值。删除final关键字。