在进行一些代码审查时,我偶然发现了这一点:
人们通常为一个装箱的布尔变量赋值Boolean.TRUE或Boolean.FALSE赋值,但对原始变量使用true/ false。最好的方法是什么?
根据我合作过的一位架构师的说法 - 他说每次你将true/分配false给一个变量时,都会创建一个新的 Boolean 实例。如果我们将布尔变量分配给静态实例 - Boolean.FALSE/ ,我们可以跳过它Boolean.TRUE。如果变量是原始变量,则完成自动拆箱。
自动拆箱是否比布尔变量的初始化更快?差异不大,我认为这只是对代码的微优化,但我想了解更多。
你是对的,性能问题主要是一种干扰。
要了解发生了什么,让我们看看在 Java 类型系统中如何对原语及其框进行建模。
当 时C extends D,这意味着 a C is-a D,或者C是 的子类型 D。分配Integerto 时Number,不需要转换,因为Integeris-a Number。在幕后,Integer和Number都由指针(对象引用)表示,赋值只是一个指针副本。
但是,boolean和之间的关系Boolean是不同的。没有extends; 没有is-a。取而代之的是装箱和拆箱转换,它们应用于某些上下文(例如,赋值、方法参数)。它们的表示是不同的。因此,当您在boolean和之间转换时Boolean,形式会发生变化(从布尔值的直接表示,到指向包含对象头和布尔有效负载的堆节点的指针。)这就是人们警告您“性能成本”的原因;这不仅仅是复制一个词。(也就是说,如果这是您程序中的性能瓶颈,那么您就会遇到更大的问题——即您的程序没有做太多事情。)
当你分配
boolean b = true;
Run Code Online (Sandbox Code Playgroud)
或者
Boolean bb = Boolean.TRUE;
Run Code Online (Sandbox Code Playgroud)
两边的类型=是相同的——boolean在第一个例子中,Boolean在第二个例子中——并且没有转换。当你做
boolean b = Boolean.TRUE;
Run Code Online (Sandbox Code Playgroud)
或者
Boolean bb = true;
Run Code Online (Sandbox Code Playgroud)
类型不同,需要进行转换。编译器默默地将这些转换为:
boolean b = Boolean.TRUE.booleanValue();
Run Code Online (Sandbox Code Playgroud)
和
Boolean bb = Boolean.valueOf(true);
Run Code Online (Sandbox Code Playgroud)
在 的特定情况下boolean,性能问题甚至比其他原语更不相关,因为只有两个布尔值,并且常量Boolean.TRUE和Boolean.FALSE是实习的。
如果您的架构师主要针对性能问题向您提供此建议,那么他/她就被误导了。如果他们的建议更多是出于简单性——使用不需要转换的正确类型的值同样容易——这是明智的。
| 归档时间: |
|
| 查看次数: |
185 次 |
| 最近记录: |