【问题标题】:Initialization required for public static final but not for public finalpublic static final 需要初始化,但 public final 不需要
【发布时间】:2015-09-07 23:34:36
【问题描述】:

我有三个常量浮点数,我想在类的构造函数中分配它们的值。

我在构造函数之前声明了所有三个常量。作为一个实验,我为每个设置了不同的修饰符:

public static float defaultdim;
public static final float maxdim;
public final float mindim;

我的 IDE Eclipse 检测到第二个常量 maxdim 的错误,即:

空白的最终字段 maxdim 可能尚未初始化

让我感到困惑的不是为什么会出现错误,而是为什么在 mindim 的情况下没有出现错误,这也是 final,考虑到错误消息与变量是 final 的事实有关。换句话说,存在错误是因为在声明期间未初始化最终变量。两个变量都是final的,都没有初始化,但是只有一种情况会出现错误。

这两个变量因修饰符 static 而不同,这表明这将是错误的原因。但是,我不明白为什么会出现这种情况,因为在 defaultdim 的情况下没有出现错误,这只是静态的,而不是最终的,并且错误本身并不涉及修饰符 static。谁能给我解释一下背后的原因?

【问题讨论】:

  • 你能在这个类的构造函数中显示代码吗?
  • 你在烦我吗? static final var 的声明必须有一个初始值,所以你会得到这个错误。
  • "我有三个常量浮点数,我想在类的构造函数中分配它们的值。"这是一个矛盾。你知道什么是常数吗?
  • @xehpuk 这句话并不矛盾——它描述了我想要的,因为这就是我想要的,所以它是真实的,并不矛盾。现在,我想在构造函数中为它们赋值的原因是因为它们基于传递给构造函数的参数。我也认识到它们应该是最终的,因为从分配开始它们的值不会改变(是的,我确实知道常量的含义)而且我也承认它们应该是静态的 - 因为它们将由给定类的所有实例共享。如果您能告诉我如何解决此问题,我将不胜感激。
  • 如果你在构造函数中赋值,那么它们就不是常量。

标签: java static initialization final


【解决方案1】:

public static float defaultdim;

static 字段将使用 default0.0Ffloat 的情况下进行初始化,如果您没有明确指定值。 (如果是int,它将有0)此外,它不是final

接下来,这两个声明都被视为 blank 缺少 initializer 的最终字段声明。


public static final float maxdim;

每个final 字段只能分配一次,并且至少在使用之前分配一次。 static 变量在加载类时初始化,由于它是 final,它在加载 class 时必须具有值,但在 static final 的情况下您会收到错误(常量) .


public final float mindim;

在上述情况下,您还没有在代码中的任何地方初始化它,编译器认为您将来也不会再初始化这个变量。您必须在使用它之前对其进行初始化。在这种情况下,您可以通过在构造函数中对其进行初始化来避免编译时间错误。

public Test(float mindim) {
    this.mindim = mindim;
}

通过这样做,您向编译器保证 mindim 将在代码中的任何位置使用之前被初始化,注意它不是 static 并且它将为每个 Object 您提供不同的副本为您的班级创建。

但是如果我需要为静态最终字段分配一个值怎么办? 传递给类的构造函数的参数?

没有。 static final 字段是 Class 相关事物,而 constructorObject 事物。你的常量应该在class被加载时被初始化,而你的构造函数将在你用new创建类的Object时被调用。在构造函数中初始化常量没有意义。如果它可以随每个对象而变化,那么它绝对不是一个常量。是的,您可以只保留您的字段 final 并根据构造函数参数分配值,因为这样每个 Object 都会有 final 值。

【讨论】:

  • 从技术上讲,首先将所有字段初始化为默认值。一个字段 final int x=1; 实际上涉及 2 次写入。第一次写入 (x=0) 可以被观察到。
  • 这解释得很好,谢谢。但是,如果我需要根据传递给类的构造函数的参数为​​静态最终字段赋值怎么办?在我的程序中,从给定类创建的所有对象都将具有相同的 defaultdim 字段,并且该 defaultdim 不会更改,这意味着修饰符应该是静态的和最终的。但是,该 defaultdim 只能从提供给构造函数的参数中确定。那该怎么办呢?
  • @bayou.io 不包括常量变量,它们永远没有默认值。
  • @xehpuk - 好吧,规范的措辞使得所有字段(包括常量变量)都首先设置为默认值。但是,对于常量静态变量,类初始化过程保证任何人的默认值都是not observable。实际上,我们可以说它们实际上没有默认值。并且 JVM 不需要先将字段归零。
  • @xehpuk - 另一方面,常量 instance 变量是另一回事;可以观察其默认值。当然,一个常量实例变量无论如何都是没有意义的。它应该是静态的。
【解决方案2】:

因为启动时的非静态变量为空

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多