这两种方法都有什么优势吗?
示例1:
class A {
B b = new B();
}
示例2:
class A {
B b;
A() {
b = new B();
}
}
这两种方法都有什么优势吗?
示例1:
class A {
B b = new B();
}
示例2:
class A {
B b;
A() {
b = new B();
}
}
当前回答
我在回复中没有看到以下内容:
在声明时进行初始化的一个可能的优势可能是,在当今的IDE中,您可以非常容易地跳转到变量的声明(大多数情况下) Ctrl-<hover_over_the_variable>-<left_mouse_click>)在你的代码中的任何地方。然后立即看到该变量的值。否则,你必须“搜索”初始化完成的位置(主要是:构造函数)。
这个优势当然是次要的,所有其他逻辑推理,但对一些人来说,“特征”可能更重要。
其他回答
我在回复中没有看到以下内容:
在声明时进行初始化的一个可能的优势可能是,在当今的IDE中,您可以非常容易地跳转到变量的声明(大多数情况下) Ctrl-<hover_over_the_variable>-<left_mouse_click>)在你的代码中的任何地方。然后立即看到该变量的值。否则,你必须“搜索”初始化完成的位置(主要是:构造函数)。
这个优势当然是次要的,所有其他逻辑推理,但对一些人来说,“特征”可能更重要。
There is one more subtle reason to initialize outside the constructor that no one has mentioned before (very specific I must say). If you are using UML tools to generate class diagrams from the code (reverse engineering), most of the tools I believe will note the initialization of Example 1 and will transfer it to a diagram (if you prefer it to show the initial values, like I do). They will not take these initial values from Example 2. Again, this is a very specific reason - if you are working with UML tools, but once I learned that, I am trying to take all my default values outside of constructor unless, as was mentioned before, there is an issue of possible exception throwing or complicated logic.
这两种方法都可以接受。注意,在后一种情况下,如果存在另一个构造函数,b=new b()可能无法初始化。将构造函数外部的初始化器代码看作一个公共构造函数,代码将被执行。
另一种选择是使用依赖注入。
class A{
B b;
A(B b) {
this.b = b;
}
}
This removes the responsibility of creating the B object from the constructor of A. This will make your code more testable and easier to maintain in the long run. The idea is to reduce the coupling between the two classes A and B. A benefit that this gives you is that you can now pass any object that extends B (or implements B if it is an interface) to A's constructor and it will work. One disadvantage is that you give up encapsulation of the B object, so it is exposed to the caller of the A constructor. You'll have to consider if the benefits are worth this trade-off, but in many cases they are.
第二种选择更可取,因为它允许在ctors中使用不同的逻辑进行类实例化,并使用ctors链接。如。
class A {
int b;
// secondary ctor
A(String b) {
this(Integer.valueOf(b));
}
// primary ctor
A(int b) {
this.b = b;
}
}
所以第二种选择更加灵活。