两种Java类构造的区别
可能重复:两种Java类构造的区别,java,constructor,Java,Constructor,可能重复: A1和A2之间有什么区别吗 class A1 { B b = new B(); A1() { } } //and class A2 { B b; A2() { b = new B(); } } 如果我实例化A1和A2类,我想知道类bb何时进行构造。在您给出的示例中没有-没有区别。它们都将在对象创建时启动对B的引用 然而,就风格而言,我个人倾向于A2 如果我们再将classA1解包一点,它相当于: class A1 {
A1
和A2
之间有什么区别吗
class A1 {
B b = new B();
A1() {
}
}
//and
class A2 {
B b;
A2() {
b = new B();
}
}
如果我实例化
A1
和A2
类,我想知道类bb
何时进行构造。在您给出的示例中没有-没有区别。它们都将在对象创建时启动对B的引用
然而,就风格而言,我个人倾向于A2
如果我们再将classA1
解包一点,它相当于:
class A1 {
B b;
{
b = new B();
}
A1() {
}
}
上面未命名的代码块是初始化块,每次创建对象时都会运行该代码块(不管调用的构造函数是什么,它在构造函数之前运行)。它在语义上等同于将所有语句放在每个构造函数的开头,这让我们回到
A2
。因此,它们是相同的。它们之间没有区别。编译器会自动将实例变量初始化放在您声明的每个构造函数中的初始化器块中
因此,编译后的第一种方法是:
class A1 {
B b;
A1() {
{
b = new B();
}
}
}
但是,第二种方式更具可读性
书中:
但是,字段声明不是任何方法的一部分,因此
不能像语句一样执行。相反,Java编译器
自动生成实例字段初始化代码并将其放入
在类的一个或多个构造函数中。初始化
代码按其在构造函数中出现的顺序插入构造函数
源代码,这意味着字段初始值设定项可以使用
在此之前声明的字段的值
在这两个类中,
B
在调用A1
和A2
的构造函数时进行构造,因为构造函数用于初始化非静态数据成员,B
是数据成员的引用类型。如果你定义
class A1{
static B b=new B();
A1(){
}
}
然后它将在类加载时加载。编译器将加载类
B
,并在类加载时生成B
的实例,否则两者之间没有区别。我假设您希望A
s实际上是构造函数,因此我重命名了它们以匹配类名。如果这不是你想要的,请随意撤销我的编辑。实际上没有区别。请参阅>以了解其工作原理。哦,谢谢@JoachimSauer。您的答案措辞相当糟糕,这里鼓励您正确拼写和语法。也许编辑它来清理一下?我个人觉得第一种方式更具可读性。这主要是因为初始化代码是完全显而易见的,特别是当有多个构造函数时,尤其是当它们不能互相调用时,那么代码就会重复。如果你删除了所有的构造函数,会发生什么呢?你必须使用第1种方法。另外,第二种方法就是增加更多的代码行,不增加任何值=代码膨胀。如果我在代码库中看到版本2,我会毫不犹豫地重构到版本1,并责骂编写它的程序员。@Bohemian。就代码复制而言,正如我所说,编译器在每个构造函数中移动初始化。。所以这部分不是使用第一部分的原因。@Bohemian。但是使用第一个或第二个始终是程序员自己的选择。这不会有多大区别。