将布尔值初始化为false或true更有效吗?

时间:2014-07-31 15:19:48

标签: java performance

在java中,如果不启动布尔值,则默认为false。所以,如果我说

boolean myFavoriteBoolean = true;

这比

更有用吗?
boolean myFavoriteBoolean = false;

我的想法是,在第一个示例中它启动false并且必须设置为true或者不是这样的情况?此外,我知道从性能角度来看这是一个没有实际意义的点,但我问,因为我很感兴趣,如果我理解Java是如何工作的。

4 个答案:

答案 0 :(得分:3)

假设您指的是boolean类型的实例字段,则答案位于the JLS chapter regarding instance creation expressions.

  

新对象包含声明的所有字段的新实例   指定的类类型及其所有超类。 作为每个新领域   实例已创建,初始化为默认值(§4.12.5)。

     

[...]

     

接下来,调用指定类类型的选定构造函数。   这导致为每个调用至少一个构造函数   类类型的超类。这个过程可以通过显式指导   构造函数调用语句(第8.8节)并详细说明   §12.5。

毕竟the super constructor calls

  

执行实例初始值设定项和实例变量初始值设定项   对于此类,分配实例变量初始值设定项的值   到相应的实例变量,按从左到右的顺序   它们以文本形式出现在类的源代码中。 [...]

所以

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编译器可以依赖的堆栈帧的自动归零。因此,您希望初始化到falsetrue的时间相同。


然而,这&#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