Java 无法在try/catch中初始化静态最终变量

Java 无法在try/catch中初始化静态最终变量,java,static,initialization,final,static-initializer,Java,Static,Initialization,Final,Static Initializer,我试图初始化一个静态的final变量。然而,这个变量是在一个可以抛出异常的方法中初始化的,因此,我需要在一个try-catch块中设置 即使我知道变量将在try或catch块上初始化,java编译器也会产生一个错误 最后一个字段a可能已经分配 这是我的代码: public class TestClass { private static final String a; static { try { a = fn(); // ERROR } catch (E

我试图初始化一个静态的final变量。然而,这个变量是在一个可以抛出异常的方法中初始化的,因此,我需要在一个try-catch块中设置

即使我知道变量将在try或catch块上初始化,java编译器也会产生一个错误

最后一个字段a可能已经分配

这是我的代码:

public class TestClass {

  private static final String a;

  static {
    try {
      a = fn(); // ERROR
    } catch (Exception e) {
      a = null;
    }
  }

  private static String fn() throws Exception {
    throw new Exception("Forced exception to illustrate");
  }

}
我尝试了另一种方法,直接将其声明为null,但它显示了类似的错误(在本例中,对我来说,这似乎完全符合逻辑)

无法分配最终字段TestClass.a


有一个优雅的解决方案吗?

您可以先将值分配给一个局部变量,然后在
try
-
catch
块之后将其分配给
final
变量:

private static final String a;

static {

    String value = null;
    try {
        value = fn();
    } catch (Exception e) {
    }
    a = value;

}

这确保了对
final
变量的单个赋值。

私有静态final字符串a=null


最终属性仅初始化一次。要么是在构造函数中,要么就是你在这里做的方式。在为“a”指定值null后,不能为其指定新值。如果没有final,可以通过fn函数设置值,因为
final
变量只能赋值一次,不能重新赋值


与try/catch无关,最终变量只能设置一次。

您不能(也不需要)在
catch
块中将
a
设置为
null

进行以下更改:

public class TestClass {


      private static final String a = setupField();

      private static String setupField() {
        String s = "";
        try {
            s = fn();
        } catch (Exception e) {
          // Log the exception, etc.
        }
        return s;
      }

      private static String fn() throws Exception {
        return "Desired value here";
      }

在您的
Try…catch
中尝试传递一个临时变量
b
,测试结果,然后分配
a
值“
final
变量在声明时只能分配一次”。那不是真的,你没有听说过空白期末考试吗?有一个链接与
try…catch
链接,在
try
中的代码被有效地“尝试”,因此如果出现错误,
a
在到达
catch
时就已经被分配了,与OP预期的相反。这将产生一个不同的错误-
空白的最终字段a可能尚未初始化
-因为现在
a
不能保证由静态初始值设定项块初始化。现在,您有两个赋值给最终变量(第一个错误)和一个应该返回字符串但没有返回语句的方法(第二个错误)。
public class TestClass {


      private static final String a = setupField();

      private static String setupField() {
        String s = "";
        try {
            s = fn();
        } catch (Exception e) {
          // Log the exception, etc.
        }
        return s;
      }

      private static String fn() throws Exception {
        return "Desired value here";
      }