何以修复错误"无法在静态块中初始化最终变量"?

时间:2017-11-03 11:29:57

标签: java

我有一个错误,我可以"无法初始化最终变量" classpath"在静态块"

/*eslint-disable no-constant-condition*/

我如何规避或解除它? THX

3 个答案:

答案 0 :(得分:1)

逻辑是正确的,但你需要初始化值而不管是什么。在这种情况下,如果发生异常,您就不会这样做。

您需要管理有异常的情况:

  1. 默认值(有效更好!)
  2. 当然,你不能只写两个会实例化它的语句,你可以使用一个局部变量

    String s;
    try{
        s = new ClassPathResource("").getFile().toString();
    } catch (IOException e){
        s = MyDefaultValue;
    }
    classPath = s;
    

    或者让静态方法为你做(对于静态块中的多个逻辑来说是混乱的)

    1. 抛出RuntimeException,这将有效并将停止执行。 (谢谢@Andy Turner和他的example

答案 1 :(得分:1)

问题在于您未在异常情况下分配变量。

假设您确实需要classPath的值是正确的,那么您也可以抛出异常,以表明某些内容已经出现了错误,并且无法使用此类:

static {
  try {
    classPath = ...
  } catch (IOException e) {
    throw new RuntimeException(e);
  }
}

(如果你真的不需要它,请删除该字段!)

虽然设置默认值没有意义,但查看为什么不能在catch块中设置一个默认值是有益的。

  try {
    classPath = ...
  } catch (IOException e) {
    classPath = defaultValue;  // classPath may already be assigned.
  }

这是因为the rules of definite assignment for try statements

  

如果满足以下所有条件,则在catch块之前肯定是未分配的:

     
      
  • 在try块之后肯定是未分配的。
  •   
  • ...
  •   

因此,在不查看必须为真的其他内容的情况下,V在try块之后肯定是未分配的(即,如果赋值成功),那么它在catch块中肯定是未分配的;因此,您无法分配其他值。

请注意,如果要分配默认值,则需要先分配局部变量:

String classPath;
try {
  classPath = ...
} catch (IOException e) {
  classPath = defaultValue;
}
A.classPath = classPath;

或定义静态方法:

class A {
  static final String classPath = getClassPath();

  static String getClassPath() {
    try {
      return ...;
    } catch (IOException e) {
      return defaultValue;
    }
  }
}

(后者的优点是你可以在单元测试中调用它;缺点是它会破坏检查方法中使用的任何静态变量(或其他被调用的方法)是否实际初始化。)

答案 2 :(得分:-1)

class A {    
private static final String classPath;
        static {
            String tempPath=null;
            try {
                tempPath=new ClassPathResource("").getFile().toString();
            } catch (IOException e) {
                e.printStackTrace();
            }
            classPath=tempPath;
        }
  }  

它会起作用。