当前位置: 首页 > 知识库问答 >
问题:

使用引发异常的方法在静态块中初始化final static变量

姜明贤
2023-03-14

考虑代码的以下部分

private static class InnerClass
{
   private static final BufferedImage connectionImage; // line A
   private static final int width;
   // other not relevant fields
   static
   {
       try
       {
           connectionImage = ImageIo.read(...); // doeasn't really matter - any method that throws exception
       }
       catch(IOException e)
       {
           // handle
          connectionImage = null; // line B
       }
       if(connectionimage != null) // line C
       {
          width = connectionImage.getWidth();
       }
       else
       {
          width =0;
       }
   }
   // rest of the class definition
}

在这种情况下,我在B行上得到“变量可能已经被赋值”,如果我在try{}块中有更多行,并且在初始化变量后导致异常,则这可能是真的。当我从A行中删除wordfinal时,它编译正常,但当我尝试使用连接图像(connectionImage)分配图像宽度/高度(也是final static)时,我稍后在静态{}块中收到警告。getWidth()(当然,如果它不为null)。警告是“初始化期间使用非最终变量”。如果我决定在A行中使用final并删除B行,我在C行中得到“variable connectionImage mage make not have been initialized”。

我的问题是:有没有一种方法可以使用抛出异常的函数(或者通常在try/catch中)在静态{}块中初始化和使用静态最终变量,或者我应该用其他方法处理?(建造商)

注意(如果相关):是的,这个类的名称是告诉你它是html" target="_blank">内部类。而且它是静态的,因为如果不是,我不能在里面声明静态字段。

我知道如何编写代码来完成我不想做的事情,但由于我的方便,我希望有这个内部类,并分离一些行为。我只是不想知道静态最终、静态阻塞、尝试/捕捉的情况。我在谷歌上找不到很好的例子,我甚至查了一下我以前的“Java Thinking”。。。

这是一个类似Java的东西——最终变量可以在静态初始化块中初始化吗?但作者并没有尝试在catch中初始化变量,而且他也并没有在赋值后的静态块中使用它们,所以他以后并没有收到“使用非final…”的警告。

共有1个答案

巫坚白
2023-03-14

基本上,您应该使用局部变量:

BufferedImage localImage = null;
try
{
    localImage = ImageIo.read(...);
}
catch (IOException e)
{
    // No need to set a value, given that it's already going to be null.
    // You probably want to log though.
}
connectionImage = localImage;

现在您可以确定您的ConnectionImage变量将被分配一次。

然后,我将对宽度使用条件运算符,这更清楚地表明只有一个赋值:

width = connectionImage != null ? connectionImage.getWidth() : 0;
 类似资料:
  • 问题内容: 这是一段Java代码: 它如何编译?初始化后已执行变量“ ture”的声明。据我所知,静态块和字段已经按照它们出现的顺序执行了。 现在,为什么实例块中的值9已被打印3次?顺便说一句,该类的实例已创建了3次。那不是功课,我正在学习Java进行认证。 问题答案: 关于第一个问题,静态块确实按照它们出现的顺序进行处理,但是在处理静态块之前,先处理声明。声明作为类 准备工作 的一部分(JLS§

  • 我有以下代码: 它从“VM参数”中读取并分配给变量。 由于静态最终变量仅在类加载时初始化,因此如何在有人忘记传递参数的情况下捕获异常。 目前,当我使用“property\u file\u location”变量时,在以下情况下会遇到异常: 若值存在,并且位置错误,则会出现FileNotFound异常 如果未正确初始化(值为null),则抛出NullPointerException 我只需要在初始化

  • 初始化的区别是什么:1)int i=47;或2)int i;{i=47;在哪些情况下我们需要第一个或第二个?

  • 问题内容: Kotlin 中的静态初始化块等效于什么? 我了解Kotlin的设计宗旨是不带静电。我正在寻找具有等效语义的东西-首次加载该类时,代码将运行一次。 我的特定用例是,我想从Android AppCompat库启用DayNight功能,并且说明要求将一些代码放入类的静态初始化块中。 问题答案: 从某种角度看,Kotlin中的s等同于Java类的静态部分。特别是,它们是在首次使用类之前初始化

  • 问题内容: 我想知道为什么默认情况下C,C ++和Java中的确切静态变量初始化为零?为什么对局部变量不是这样? 问题答案: 为什么要对静态变量进行确定性初始化而对局部变量不进行初始化? 了解如何实现静态变量。 它们的内存在链接时分配,并且它们的初始值也在链接时提供。 没有运行时开销。 另一方面,用于局部变量的内存是在运行时分配的。堆栈必须增长。你不知道以前在那里。如果需要,可以清除该内存(将其清

  • 问题内容: 据我了解,“静态初始化块”用于设置静态字段的值(如果无法在一行中完成的话)。 但是我不明白为什么我们需要为此设置一个特殊的块。例如,我们将字段声明为静态(无值分配)。然后编写几行代码,生成并为上面声明的静态字段分配一个值。 为什么我们需要在这样一个特殊的块这样的行:? 问题答案: 在非静态块: 每次构造类的实例时被调用。在静态块只被调用一次,当类本身初始化,无论该类型的有多少对象创建。