显式初始化基本类型数据的方法

9

我知道Java原始类型有默认的初始化值,例如int的默认值为0

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

下面是我程序的一部分:

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;
}
}

5
根据我的研究,似乎我不应该依赖这些数值。哎?语言规范对你来说不够可靠吗? - fge
2
这与依赖于值的大小关系较小,更多地是要向其他程序员明确你正在使用的值。 - Boris the Spider
如果您不需要默认值,并且逻辑上您的类的每个实例都应该将实例变量设置为至少一个特定值,则可以使用构造函数来实现。 - AllTooSir
7个回答

4
使用Java默认值是完全可以的,您不需要显式地初始化类的实例或静态字段。Java语言规范要求这样做,因此任何语言的实现都必须遵守。换句话说,如果使用成员变量的默认值,则您的代码将保持100%可移植性。这适用于基本类型和引用类型(后者使用null进行初始化)。
更多详细信息请参见Java Language Specification第81页。
“4.12.5变量的初始值”中指出:
程序中的每个变量在使用前都必须具有一个值: - 每个类变量、实例变量或数组组件在创建时都会被初始化为默认值
唯一需要提供显式初始化的情况是在声明局部变量时:
必须通过初始化或赋值显式地给局部变量赋值,以使其可以使用明确分配的规则进行验证。
但是,由于未初始化局部变量是编译时错误,因此编译器将在运行程序之前定位每个缺少的初始化。

1

根据我的研究,似乎我不应该依赖这些值。

你可以依赖它们。没有害处,因为它已经默认完成了,正如你所知道的那样。

我是否应该总是提供明确的初始化,如果是的话,应该在哪里提供?

对于基本类型,不需要提供显式初始化,我更喜欢不提供。我很少这样做,并且看到人们为实例变量进行初始化,例如 int i = 0;。但是,如果您谈论的是局部变量,则需要给它们明确的值。默认值在那里不是隐含的。

但是,当涉及非基元类型时,您应该进行显式初始化,可以在声明点或构造函数内进行,因为默认值为null,如果不加注意可能会导致NPE。在声明点进行初始化的好处是,你不必在每个构造函数中都放置初始化。


1
应避免使用默认或“虚拟”变量初始化本地变量。这会抑制编译器执行的静态分析,可能会提醒您忽略的代码路径。例如,如果声明了一个本地变量,并在没有赋值的情况下稍后读取它,则编译器将向您发出警报。如果您使用无意义的默认值进行初始化,则编译器将无法检测到您的错误。因此,请将声明留空,或者等到可以使用真实值初始化变量时再声明它。 - erickson
@erickson。没错,我就是这个意思。在需要时声明局部变量是一个很好的习惯。当你遇到一些奇怪的问题时,这可以节省很多工作。 - Rohit Jain

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可能能够在运行时优化这种字节码。


0
如果你真的很担心这个问题,可以在构造函数中初始化变量。然而,我从来没有见过数值原始类型被初始化为除零以外的任何值。
我认为只有在使用某些自定义(且质量较差)的JVM时才需要担心这个问题。

0

成员变量将使用默认值进行初始化。因此,您不必担心这个问题。但是,如果您仍然想要使用默认值或其他值进行初始化,您可以在构造函数中设置它们。


没有构造函数:public class A { public int num = 2; public void A() {
}
}
- Ramin Darvishov
1
在构造函数中初始化是更好的选择。 - stinepike
可能是可以的。我只是提供另一种方法。 - Ramin Darvishov
太好了,我以为我的答案因为建议在�造函数中�始化而被踩了� - stinepike

0

通常情况下,您编写的代码应该尽可能做出最少令人惊讶的事情。如果您觉得未明确初始化的变量的默认值为零令人惊讶,那么也许您应该确保始终分配一个初始值,即使它是零。

在您展示的代码中,我的个人偏好是在声明时将变量初始化为0。这只是因为变量的第一个操作是+=,对我来说依赖于数字操作的默认值感觉不对。虽然没有什么好的理由,因为它可以正常工作,但它感觉不对。


0

默认值是可靠的。


实际上,它们比显式清零更可靠,因为默认赋值发生在所有其他操作之前。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接