闲来无事,开始研究JDK源码(jdk 1.5 b2),先找了一个最简单的java.lang.Boolean开始解剖。
由于水平有限,难免有不少错误,还请大家指正!
首先我们剔除所有的方法和静态变量,Boolean的核心代码如下:
public final class Boolean implements java.io.Serializable,Comparable
{
private final boolean value;
}
很明显,凡是成员变量都是final类型的,一定是immutable class,这个Boolean和String一样,一旦构造函数执行完毕,实例的状态就不能再改变了。
Boolean的构造函数有两个:
public Boolean(boolean value) {
this.value = value;
}
public Boolean(String s) {
this(toBoolean(s));
}
都很简单就不多说了。
另外注意到Boolean类实际上只有两种不同状态的实例:一个包装true,一个包装false,Boolean又是immutable class,所以在内存中相同状态的Boolean实例完全可以共享,不必用new创建很多实例。因此Boolean class还提供两个静态变量:
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
这两个变量在Class Loader装载时就被实例化,并且申明为final,不能再指向其他实例。
提供这两个静态变量是为了让开发者直接使用这两个变量而不是每次都new一个Boolean,这样既节省内存又避免了创建一个新实例的时间开销。
因此,用
Boolean b = Boolean.TRUE;
比
Boolean b = new Boolean(true);
要好得多。
如果遇到下面的情况:
Boolean b = new Boolean(var);
一定要根据一个boolean变量来创建Boolean实例怎么办?
推荐你使用Boolean提供的静态工厂方法:
Boolean b = Boolean.valueOf(var);
这样就可以避免创建新的实例,不信看看valueOf()静态方法:
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
这个静态工厂方法返回的仍然是两个静态变量TRUE和FALSE之一,而不是new一个Boolean出来。虽然Boolean非常简单,占用的内存也很少,但是一个复杂的类用new创建实例的开销可能非常大,而且,使用工厂方法可以方便的实现缓存实例,这对客户端是透明的。所以,能用工厂方法就不要用new。
和Boolean只有两种状态不同,Integer也是immutable class,但是状态上亿种,不可能用静态实例缓存所有状态。不过,SUN的工程师还是作了一点优化,Integer类缓存了-128到127这256个状态的Integer,如果使用Integer.valueOf(int i),传入的int范围正好在此内,就返回静态实例。
hashCode()方法很奇怪,两种Boolean的hash code分别是1231和1237。估计写Boolean.java的人对这两个数字有特别偏好:
public int hashCode() {
return value ? 1231 : 1237;
}
equals()方法也很简单,只有Boolean类型的Object并且value相等才返true:
public boolean equals(Object obj) {
if (obj instanceof Boolean) {
return value == ((Boolean)obj).booleanValue();
}
return false;
}
顺便提一句:很多人写equals()总是在第一行写:
if (obj==null) return false;
其实完全没有必要,因为如果obj==null,下一行的
if (obj instanceof Type)
就肯定返回false,因为(null instanceof AnyType) = false。
详细内容请参考《Effective Java》第7条:Obey the general contract when overriding equals。
其他的方法如toString()就更简单了,只要稍微熟悉java的程序员相信都能写出来,我就不多说了。
★ 总结 ★
1.如果一个类只有有限的几种状态,考虑用几个final的静态变量来表示不同状态的实例。
例如编写一个Weekday类,状态只有7个,就不要让用户写new Weekday(1),直接提供Weekday.MONDAY即可。
2.要防止用户使用new生成实例,就取消public构造函数,用户要获得静态实例的引用有两个方法:如果申明public static var就可以直接访问,比如Boolean.TRUE,
第二个方法是通过静态工厂方法:Boolean.valueOf(?)
3.如果不提供public构造函数,让用户只能通过上面的方法获得静态变量的引用,还可以大大简化equals()方法:
public boolean equals(Object obj) {
return this==obj;
}
可以直接用==比较引用,绝对没有问题,而且效率最高。
4. 为什么JDK的Boolean没有实现上面第3点?因为那两个static变量TRUE和FALSE是在jdk 1.2以后才有的,由于前面的版本已经把构造函数申明为public,所以为了保持客户端代码能够不修改也在后面的版本中运行,只好继续提供public 构造函数。
分享到:
相关推荐
BooleanRT, 实现2个物体间的布尔运算 The extension provides the following functions: 1- Real-time or per-click Boolean execution. 2- Material, UV and texture preservation. 3- Saving to prefab. 4- ...
本文将深入探讨ClassLoader的工作原理,源码分析以及实际应用案例。 首先,我们需要理解ClassLoader的基本概念。ClassLoader是Java中的一个核心组件,它遵循"按需加载"的原则,只有当类被引用时才会加载。Java的类...
"Boolean RT资源包"专门针对这种情况,提供了高效的几何体布尔运算功能。布尔运算源于数学中的集合论,用于描述集合之间的逻辑关系,如并集、交集和差集。在3D建模中,它允许我们将一个物体与另一个物体相交、合并或...
《Unity中的实时3D布尔运算:Boolean RT》 在Unity引擎中,开发3D游戏或交互式应用时常需要处理复杂的3D模型与场景交互。传统的3D建模工具提供了布尔运算功能,允许用户通过合并、相交或相减几何体来创建复杂的形状...
虽然标题与描述存在不一致之处(标题提到的是`Boolean`类而描述提到的是`Integer`类),但根据提供的部分源代码内容,我们可以确定文档主要涉及`Boolean`类的源码分析。因此,以下内容将围绕`Boolean`类展开。 ### ...
Unity 几何体布尔运算BooleanRT,Boolean RT.unitypackage,unity3d布尔运算插件。
4. **源码分析**:`Test_sget_boolean.c`文件是测试`sget-boolean`函数的源代码。在这个文件中,开发者会定义一系列测试用例来覆盖函数的各种输入情况,包括边缘情况和异常情况,比如空字符串、无效布尔表示等。 5....
通过上面的分析,我们可以得出结论:在 Java 中,大部分情况下,我们可以使用基本数据类型 boolean 就可以了。但是,如果我们需要将布尔值封装到集合中,那么我们需要使用 Boolean。这是因为 Boolean 可以被实例化,...
在学习Shiro时,源码分析是一个深入了解其内部工作原理的有效方式。本文将继续上一篇文章的案例,深入分析Shiro的Subject和Session机制,以及SecurityManager在创建Subject时所扮演的角色和过程。 首先,Shiro中的...
Unity Boolean CSG插件的使用
Retrofit之OKHttpCall源码分析 Retrofit之OKHttpCall源码分析是对Retrofit框架中OKHttpCall类的源码进行了深入分析,涉及到OKHttpCall的实现原理、方法调用机制等方面的内容。本篇文章将带领读者深入探究OKHttpCall...
boolean_approach
Vector 底层结构和源码分析 Vector 是 Java 中一个古老的集合类,用于存储和管理对象的集合。它和ArrayList一样,都是基于数组实现的,但是 Vector 是线程同步的,即线程安全的。在本文中,我们将深入分析 Vector ...
因此,如果需要将字符串"false"转换为布尔值false,不能直接使用Boolean构造函数,而应该使用其他方法。一种可能的解决方案是使用字符串比较: ```javascript var hasAuth = '$!auth'; if (hasAuth === 'true') { ...
Boolean RT.unitypackage,unity3d布尔运算插件。
Screen Space Boolean Subtract Shader 动态计算模型布尔值,源代码
Struts2是一个流行的Java web框架,它提供了许多功能来简化应用程序开发,...同时,深入学习Struts2的源码也能帮助理解其内部工作原理,提高问题解决能力。记得定期更新Struts2到最新版本,以获取最新的修复和改进。