public static final 需要初始化但 public final 不需要

Initialization required for public static final but not for public final

我有三个常量浮点数,我想在 class.

的构造函数中分配它们的值

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

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

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

the blank final field maxdim may not have been initialized

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

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

因为开始时的非静态变量为空

public static float defaultdim;

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

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


public static final float maxdim;

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


public final float mindim;

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

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

通过这样做,您已向编译器保证 mindim 将在代码中的任何地方使用之前进行初始化,注意 它不是 static,它将您为 class.

创建的每个 Object 都有不同的副本

But what if I need to assign a value to a static final field based on an argument passed to the constructor of the class?

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

都会有 final