当我定义Java类时:
class A {
private String str = "init method 1";
public A() {
str = "init method 2";
}
}
我可以在定义它时初始化str
或在构造函数中初始化它。我的问题是这两种方法的区别是什么?首选哪种方法?
答案 0 :(得分:4)
初始化块值在构造函数赋值之前分配。
因此,将首先分配值init member 1
,然后分配init member 2
。
class InitBlocksDemo {
private String name ;
InitBlocksDemo(int x) {
System.out.println("In 1 argument constructor, name = " + this.name);
}
InitBlocksDemo() {
name = "prasad";
System.out.println("In no argument constructor, name = " + this.name);
}
/* First static initialization block */
static {
System.out.println("In first static init block ");
}
/* First instance initialization block */
{
System.out.println("In first instance init block, name = " + this.name);
}
/* Second instance initialization block */
{
System.out.println("In second instance init block, name = " + this.name);
}
/* Second static initialization block */
static {
System.out.println("In second static int block ");
}
public static void main(String args[]) {
new InitBlocksDemo();
new InitBlocksDemo();
new InitBlocksDemo(7);
}
}
此输出,
In first static init block
In second static int block
In first instance init block, name = null
In second instance init block, name = null
In no argument constructor, name = prasad
In first instance init block, name = null
In second instance init block, name = null
In no argument constructor, name = prasad
In first instance init block, name = null
In second instance init block, name = null
In 1 argument constructor, name = null
程序流程如下。
InitBlocksDemo
被加载到JVM中。main
方法。new InitBlocksDemo();
导致无参数构造函数被调用。super
无参数构造函数的默认调用,因此控制转到超类,即Object
类null
。null
new InitBlocksDemo(7);
导致调用单参数构造函数。其余的过程是一样的。唯一的区别是名称未重新分配新值,因此它将打印null
答案 1 :(得分:3)
区别在于分配何时发生。 在构造函数运行之前为字段分配const值,因此如果将此行添加到构造函数中:
System.out.println(str);
在构造函数中指定较新的值之前,您将看到旧的值。
除了那之外没有太大的区别,使用的主要是个人偏好。
我个人可以直接指派作为现场声明的一部分 - 这就是我所做的。
答案 2 :(得分:3)
它们之间没有区别,编译器将初始化块复制到构造函数
如果您,反编译生成的类文件
class A {
private String str1 = "init method 1";
private String str2;
public A() {
str2 = "init method 2";
}
public A(String str2) {
str2 = str2;
}
}
你可以找到
class A
{
private String str1;
private String str2;
public A()
{
str1 = "init method 1";
str2 = "init method 2";
}
public A(String str2)
{
str1 = "init method 1";
str2 = str2;
}
}
答案 3 :(得分:1)
根据我的个人经验,它完全取决于对象初始化的成本或详细程度。其次,您还可以将其视为懒惰创建与主动创建。如果只涉及构造函数,我通常会在实例变量级别创建对象。如果还有进一步的调用来初始化有问题的成员,那么肯定会将调用移动到构造函数或需要初始化的方法。
这就是为什么使用工厂方法模式,将实际的对象创建委托给另一个类。