Java 常量变量可能已被赋值

Java 常量变量可能已被赋值,java,exception,Java,Exception,我真的需要帮助。我不知道怎么解决这个问题。我想从属性文件加载一些常量。我认为,FileNotFoundException的Catch只能在properties.load()上抛出。但是艾德说 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

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

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);
    }
}
非常感谢。

问题在于:

    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_ID
VK_MAX_ID
MAX_USERS_TO_PARSE_AT_ONCE
声明为,这意味着一旦分配,就不能更改其值。删除
final
关键字。

Java编译器没有看到我们可以看到的内容——一次
MAX\u USERS\u to\u PARSE\u的赋值
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\u USERS\u TO\u PARSE\u
final
,而不必使用
try catch
,并在
catch块中设置值,您可以使用简单的
if else
替换所有这些内容,而无需删除
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
块分配常量的原因是,即使您知道在第一次设置值之前会捕获异常,编译器也不知道这一点。它必须假设异常可以抛出
try
块中的任何位置。因此,从编译器的角度来看,最终变量可能在捕获异常之前就已经设置好了,因此它会给出错误。

我知道这是最终变量。但我不明白第一次分配到哪里?我认为这一例外情况将在任何分配之前被捕获。没有?我想你刚刚注意到了,但是你只能接受一个问题的答案。但是,当您达到15个代表时,您将能够投票选出所有您认为有用的答案。谢谢您的解释)