在java中,如果不启动布尔值,则默认为false。所以,如果我说
boolean myFavoriteBoolean = true;
这比
更有用吗?boolean myFavoriteBoolean = false;
我的想法是,在第一个示例中它启动false
并且必须设置为true
或者不是这样的情况?此外,我知道从性能角度来看这是一个没有实际意义的点,但我问,因为我很感兴趣,如果我理解Java是如何工作的。
答案 0 :(得分:3)
假设您指的是boolean
类型的实例字段,则答案位于the JLS chapter regarding instance creation expressions.
新对象包含声明的所有字段的新实例 指定的类类型及其所有超类。 作为每个新领域 实例已创建,初始化为默认值(§4.12.5)。
[...]
接下来,调用指定类类型的选定构造函数。 这导致为每个调用至少一个构造函数 类类型的超类。这个过程可以通过显式指导 构造函数调用语句(第8.8节)并详细说明 §12.5。
执行实例初始值设定项和实例变量初始值设定项 对于此类,分配实例变量初始值设定项的值 到相应的实例变量,按从左到右的顺序 它们以文本形式出现在类的源代码中。 [...]
所以
boolean val = false;
//and
boolean val = true;
表现完全相同。
答案 1 :(得分:1)
如果谈论有默认值的字段:创建的对象归零,那么只需将其设置为true就需要一条指令 - 人们会想到。
然而,这是一个愚蠢的案例,证明了初始化和默认初始化之间的区别:
class A {
A() {
b();
}
void b() {
}
}
class B extends A {
boolean c = false;
boolean c2;
@Override
void b() {
c = true;
c2 = true;
}
B() {
super();
System.out.printf("%s %s%n", c, c2);
}
}
new B();
这将产生
false true
原因:在调用super()
之后(或者在构造函数的开头没有超级),所有字段初始化都会发生:此时c
设置为true
,但现在已被初始化为false
。
这是定义的行为,以及从不在构造函数中调用可覆盖函数的原因。
还要注意,在第一个B.b()
中,B的所有字段仍然具有默认值。
<强> 所以: 强>
我删除了初始化= null
(清理遗留代码)导致错误。
答案 2 :(得分:1)
如果变量是实例变量或静态变量,则变量默认初始化为false
,并且JIT编译器很可能可以利用它并优化显式初始化false
。 (实际上,堆内存由垃圾收集/堆管理器归零,无论内存将如何使用,都会发生这种情况。)
如果变量是局部变量,则没有默认初始化,并且(通常)没有JIT编译器可以依赖的堆栈帧的自动归零。因此,您希望初始化到false
或true
的时间相同。
然而,这&#34;气味&#34;过早优化。一旦代码被JIT编译,实际差异可能是一个或两个本机代码指令。可能会对您的申请产生重大影响。此外,改变你的程序以利用(假设的)性能差异很可能会使你的代码不那么可读,并且已经开始knock&#34;对程序其他部分的性能产生影响。
最佳做法是在以下情况下只考虑这种微优化:
您有明确证据表明需要进行优化;即您的应用程序 运行速度太慢,无法用于代表性基准测试,
您有明确的证据表明声明和初始化变量的代码实际上是性能瓶颈;即分析器告诉你这个。
答案 3 :(得分:1)
布尔字段在JVM级别默认为false。初始化为true会产生3个额外的字节码指令。
public class BoolTest {
public boolean foo;
}
编译到
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
比较初始化为真
public class BoolTest {
public boolean foo = true;
}
编译到
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_1
6: putfield #2; //Field foo:Z
9: return