这两种方法都有什么优势吗?
示例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();
}
}
当前回答
class MyClass extends FooClass {
String a = null;
public MyClass() {
super(); // Superclass calls init();
}
@Override
protected void init() {
super.init();
if (something)
a = getStringYadaYada();
}
}
关于以上,
String a = null;
Null init可以避免,因为它是默认值。 然而,如果您需要另一个默认值, 然后,由于初始化顺序不受控制, 我将修改如下:
class MyClass extends FooClass
{
String a;
{
if( a==null ) a="my custom default value";
}
...
其他回答
我个人的“原则”(几乎从未被打破)是:
的开头声明所有变量 一块 使所有变量为final,除非它们 不能 每行声明一个变量 永远不要在某处初始化变量 宣布 只初始化a中的东西 构造函数时使用 的构造函数 初始化
我的代码是这样的:
public class X
{
public static final int USED_AS_A_CASE_LABEL = 1; // only exception - the compiler makes me
private static final int A;
private final int b;
private int c;
static
{
A = 42;
}
{
b = 7;
}
public X(final int val)
{
c = val;
}
public void foo(final boolean f)
{
final int d;
final int e;
d = 7;
// I will eat my own eyes before using ?: - personal taste.
if(f)
{
e = 1;
}
else
{
e = 2;
}
}
}
This way I am always 100% certain where to look for variables declarations (at the start of a block), and their assignments (as soon as it makes sense after the declaration). This winds up potentially being more efficient as well since you never initialize a variable with a value that is not used (for example declare and init vars and then throw an exception before half of those vars needed to have a value). You also do not wind up doing pointless initialization (like int i = 0; and then later on, before "i" is used, do i = 5;.
我非常重视一致性,所以遵循这个“规则”是我一直在做的事情,它使处理代码变得更容易,因为你不需要到处寻找东西。
你的里程可能会有所不同。
其实很不一样:
声明发生在构建之前。因此,如果在两个位置都初始化了变量(本例中为b),构造函数的初始化将取代在类级别所做的初始化。
所以在类级别声明变量,在构造函数中初始化它们。
我认为这几乎只是一个品味问题,只要初始化是简单的,不需要任何逻辑。
如果不使用初始化块,构造函数方法会更脆弱一些,因为如果稍后添加第二个构造函数而忘记在那里初始化b,则只有在使用最后一个构造函数时才会得到一个空b。
有关Java中初始化的更多细节,请参阅http://java.sun.com/docs/books/tutorial/java/javaOO/initial.html(以及关于初始化器块和其他不为人所知的初始化特性的解释)。
我今天以一种有趣的方式被烧伤了:
class MyClass extends FooClass {
String a = null;
public MyClass() {
super(); // Superclass calls init();
}
@Override
protected void init() {
super.init();
if (something)
a = getStringYadaYada();
}
}
看到错误了吗?结果是,在父类构造函数被调用之后才调用a = null初始化式。由于超类构造函数调用init(), a的初始化之后是a = null初始化。
第二种选择更可取,因为它允许在ctors中使用不同的逻辑进行类实例化,并使用ctors链接。如。
class A {
int b;
// secondary ctor
A(String b) {
this(Integer.valueOf(b));
}
// primary ctor
A(int b) {
this.b = b;
}
}
所以第二种选择更加灵活。