9

我了解 Java 原语具有默认的初始化值;例如0对于int

从我的研究看来,我不应该依赖这些价值观。我是否应该始终提供显式初始化,如果是,在哪里?

这是我的程序的一部分:

public class Calculator {

// Initialize value where it's declared?
private int value;

public Calculator() {
    // Initialize value in constructor?
}

public void add(int other) {
    value += other;
}
}
4

7 回答 7

4

使用 Java 生成的默认值是绝对可以的,您不需要显式static初始化class. Java 语言规范对此有要求,因此该语言的任何实现都必须遵守。换句话说,如果您使用成员变量的默认值,您的代码将保持 100% 的可移植性。这适用于原始类型和引用类型(后者用 初始化null)。

有关更多详细信息,请参阅第 81 页的Java 语言规范。

4.12.5 变量初始值

程序中的每个变量在使用其值之前都必须有一个值: - 每个类变量、实例变量或数组组件在创建时都使用默认值进行初始化

必须提供显式初始化的唯一情况是声明局部变量时:

局部变量在使用前必须通过初始化或赋值显式地赋予一个值,这种方式可以使用明确赋值的规则进行验证。

然而,由于初始化本地失败是一个编译时错误,编译器会在你运行程序之前查明每一个缺失的初始化。

于 2013-06-20T17:16:50.433 回答
1

从我的研究看来,我不应该依赖这些价值观。

你可以依靠他们。不会有任何危害,因为您已经知道默认情况下会这样做。

我是否应该始终提供显式初始化,如果是,在哪里?

对于原语,没有必要提供显式初始化,我不想这样做。我很少看到人们进行初始化int i = 0;,例如变量。但是,如果你在谈论局部变量,那么你需要给它们明确的值。默认值不是隐含的。

但是当这种情况出现在非原始的情况下,那么您应该在声明点或构造函数内部进行显式初始化,因为默认值是,如果不注意null,这可能会导致NPE。在声明点初始化的好处是,您不必将初始化放在每个构造函数中。

于 2013-06-20T17:16:46.467 回答
0

您可以清楚地信任具有默认值的 JVM 原始初始化。


顺便说一句,显式初始化将被转换为在这种情况下无用的字节码。

假设你有这个类:

public class PrimitiveInitialization {
    int i = 0;
    int j;
}

相应的字节码将是

class PrimitiveInitialization {
  I i
  I j

  public <init>()V
   L0
    LINENUMBER 8 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
   L1
    LINENUMBER 10 L1
    ALOAD 0
    ICONST_0
    PUTFIELD PrimitiveInitialization.i : I
    RETURN
   L2
    LOCALVARIABLE this LPrimitiveInitialization; L0 L2 0
    MAXSTACK = 2
    MAXLOCALS = 1
}

我们可以看到显式初始化为变量添加了一些字节码操作i

也就是说,您必须始终更喜欢代码可读性,因为 JIT 可能能够在运行时优化这种字节码。

于 2013-06-20T17:36:29.257 回答
0

如果您真的担心这一点,请在构造函数中初始化变量。但是,我从未见过初始化为零以外的任何数字原语。

我认为,如果您正在使用一些自定义(和糟糕的)JVM,您只需要担心这一点。

于 2013-06-20T17:16:37.013 回答
0

成员变量将使用默认值初始化。所以你不必担心。但是,如果您想使用默认值或其他值进行初始化,您可以在构造函数中设置它们

于 2013-06-20T17:16:54.560 回答
0

作为一般规则,您编写的代码应该总是做最不令人惊讶的事情。如果您觉得未显式初始化的变量的默认值为零令人惊讶,那么也许您应该确保始终分配初始值,即使它为零。

在您显示的代码中,我个人的偏好是在声明时将变量初始化为 0。这仅仅是因为对变量的第一个操作是+=,对我来说,依靠数值操作的默认值感觉是错误的。没有充分的理由这样做,因为它会正常工作,因为它只是感觉不对。

于 2013-06-20T17:21:37.923 回答
0

默认值是可靠的。


实际上,它们比显式归零“更”可靠,因为默认分配发生在所有其他操作之前。

于 2013-06-20T18:33:33.540 回答