java 最终字段可能已被分配:编译器错误?

问题描述 投票:0回答:1

我有以下课程:

public class FileId {

    final long length;
    final String hash;

    FileId(File file) {
        assert !file.isDirectory();
        this.length = file.length();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            try (FileInputStream fis = new FileInputStream(file)) {
                byte[] dataBytes = new byte[1024];

                int nread = 0;
                while ((nread = fis.read(dataBytes)) != -1) {
                    md.update(dataBytes, 0, nread);
                }
                this.hash = md.toString();
            } catch (IOException e) {
                // TBD: add warning 
                this.hash = "";
            }
        } catch (NoSuchAlgorithmException nsae) {
            // TBD: emit warning 
            this.hash = "";
        }
    }
}

hash
的最后两个赋值会产生编译器错误

variable hash might already have been assigned

怎么会这样?
例如,如果完成第一个分配,则不会引发异常 所以其他分配不会发生。

我的错误在哪里?

java final
1个回答
1
投票

你没有错,但你正在应用比编译器更深入的分析。

try
catch
本质上不是独占块,因此编译器想要确认
try
中根本没有赋值。用JLS的话来说:

  • V 在
    catch
    块之前肯定未分配,当且仅当满足以下所有条件时:
    • V 在
      try
      块之后肯定未分配。

由于您在

try
块中进行了赋值,因此您的变量不满足最终字段在赋值之前“绝对未赋值”的要求。

© www.soinside.com 2019 - 2024. All rights reserved.