有什么区别:
public class A
{
private int x = 1;
A() {}
}
和
public class A
{
private int x;
A() { x = 1; }
}
,如果有的话?
答案 0 :(得分:3)
如果从实际角度提出问题,不同之处在于,对于第二种形式的初始化,您必须为您编写的每个构造函数重复它,是否要编写许多重载的构造函数。
答案 1 :(得分:2)
答案 2 :(得分:2)
来自JLS 12.5:
每当创建新的类实例时,都会分配内存空间 为它提供了在类中声明的所有实例变量的空间 type和在每个超类中声明的所有实例变量 类类型,包括可能隐藏的所有实例变量。
进一步说明:
在对新创建的对象的引用之前返回为 结果,处理指示的构造函数以初始化new 使用以下过程对象:
将构造函数的参数分配给新创建的 此构造函数调用的参数变量。
如果此构造函数以显式构造函数调用开头 同一个类中的另一个构造函数(使用此),然后进行求值 递归地构造函数调用的参数和过程 使用这五个相同的步骤。如果该构造函数调用完成 突然之间,由于同样的原因,这个程序突然完成; 否则,继续步骤5.
此构造函数不以显式构造函数开头 在同一个类中调用另一个构造函数(使用此方法)。如果 这个构造函数用于Object以外的类,然后是这个 构造函数将以a的显式或隐式调用开始 超类构造函数(使用超级)。评估参数和 使用这些来递归地处理超类构造函数调用 同样的五个步骤。如果该构造函数调用突然完成, 然后由于同样的原因,这个程序突然完成。除此以外, 继续第4步。
执行实例初始值设定项和实例变量 此类的初始值设定项,分配实例变量的值 初始化器到相应的实例变量中 从左到右的顺序,它们在源代码中以文本形式出现 为了上课。如果执行任何这些初始化程序导致 异常,然后没有处理进一步的初始化程序 程序突然完成同样的异常。除此以外, 继续步骤5.(在一些早期实现中,编译器 错误地省略了代码以初始化字段(如果字段) 初始化表达式是一个常量表达式,其值相等 到其类型的默认初始化值。)
- 醇>
执行此构造函数的其余部分。如果说 执行突然完成,然后此过程突然完成 出于同样的原因。否则,此过程正常完成。
本质上,JVM为变量x
(以及超类的所有实例变量)创建内存,并使用默认值(0
x
)初始化每个实例。在返回类A
的新实例之前,它现在将执行构造函数体。
答案 3 :(得分:2)
1 /写入的赋值在初始化期间的不同时间发生 - 构造函数是在实例初始化期间执行的最后一件事。
2 /编译器提供的x变量的隐式初始化为零。所以这两项任务都是多余的。
答案 4 :(得分:1)
实际上没什么。如果您不自己初始化,则类范围内的变量将初始化为默认值。对于int
类型,这将是0.有一个基元here的默认初始化值表。
重要的是要注意,这不适用于本地基元,并且始终在使用前将这些初始化为值。
答案 5 :(得分:0)
不同之处在于,在第二个你可以有一个构造函数
public class A
{
private int x;
A(String something) { }
}
如果你添加第二个构造函数并且忘记调用this()那么你就不会初始化你的x而将它保留为默认值。 所以我建议你使用第一个,因为它不易出错。
答案 6 :(得分:0)
在第一种情况下,
您不需要将变量初始化为0,因为默认情况下所有成员变量都初始化为0.
您不需要编写no arg构造函数,因为默认情况下也会这样做。
在第二种情况下,你再次不需要那个将变量设置为0的构造函数。如果你想给出0以外的一些值,可能需要它,比如x=20;
答案 7 :(得分:0)
在这种情况下,没有。
如果x是静态的,那么它将不会被初始化,直到“new A();”编码。
看到x不是静态的,处理实际上是相同的,但是你应该注意JLS中的细微差别,特别是如果A扩展了另一个类,例如。
如果你在构造函数中使用x做了一些事情,那么在它被初始化之前(如例2所示),例如int b = x;不要指望b为1.在我的头顶,你要么在编译器上得到错误/警告,要么b等于零。