当我定义一个 Java 类时:
class A {
private String str = "init method 1";
public A() {
str = "init method 2";
}
}
我可以str
在定义它时初始化它,也可以在构造函数中初始化它。我的问题是这两种方法有什么区别?首选哪种方法?
当我定义一个 Java 类时:
class A {
private String str = "init method 1";
public A() {
str = "init method 2";
}
}
我可以str
在定义它时初始化它,也可以在构造函数中初始化它。我的问题是这两种方法有什么区别?首选哪种方法?
初始化块值是在构造函数分配它们之前分配的。
所以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);
该语句导致调用单参数构造函数。其余过程相同。唯一的区别是 name 没有重新分配一个新值,因此它将打印null
不同之处在于分配发生的时间。在构造函数运行之前为字段分配 const 值,因此如果将此行添加到构造函数:
System.out.println(str);
在您在构造函数中分配新值之前,您会看到旧值就在那里。
除此之外没有太大的区别,使用哪个主要是个人喜好。
我个人可以直接分配作为字段声明的一部分 - 这就是我所做的。
它们之间没有区别,编译器将初始化块复制到构造函数
如果你,反编译生成的类文件
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;
}
}
以我个人的经验,这一切都与对象初始化的昂贵或详细程度有关。其次,您也可以将其视为惰性创建与主动创建。如果只涉及构造函数,我通常会在实例变量级别创建对象。如果有进一步的调用来初始化相关成员,那么肯定会将该调用移至构造函数或需要初始化的方法。
这就是为什么使用工厂方法模式,将实际的对象创建委托给另一个类。