众所周知,java对常见的原始数据类型都提供了对应的封装类型,增加一些常用的特性(如 计算hash值、比较相等、类型转换等),以扩展他们对数据处理的能力,使得他们更好地适应面向对象编程的各种场景。今天,我们首先来学习 boolean 布尔型对应的封装类型。
1. 定义
首先来看看定义(下图),可以看到,Boolean 实现了序列化和比较接口,说明一个 Boolean 对象是可以序列化的;是可以比较大小的;另外,注意 final 修饰符,Boolean 不可被继承。
2. 属性
下图是 Boolean 类型的重要属性字段:
2.1. 枚举静态引用
我们知道,原始 boolean 类型只存在两个值:true 和 false。既然只有两种值,那么封装类就干脆定义两个静态的引用,分别保持对两个值对象实例的引用,它们会在类加载的时候被初始化。
2.2. 值
注意 value 字段的 final 修饰符,说明一个 Boolean 类型对象的值是不允许改变的。
2.3. 类型引用
我们知道,虚拟机在类加载的时候,会为每个类创建一个 Class 对象,用于在运行时表示这个类的类型信息(比如:类名、全类名、有哪些修饰符、有哪些方法和属性、有哪些注解等),那么原始数据类型也不例外,上图 TYPE 就是保持对这个 Class 对象的引用。
3. 构造方法
Boolean 有两个构造方法,分别接收原始数据类型 boolean 值和字符串 “true”或者“false”(忽略大小写)如果传的字符串为 null,那么自动认为该对象值为 false。
上图中红框中注释说明了,不建议使用构造方法,而建议使用静态工厂 valueOf(boolean) 方法,下面是 valueOf 方法代码。可以看出,静态工厂方法会直接返回类属性 TRUE 或 FALSE 引用的静态对象实例,他们在类加载的时候已经实例化。这样就不需要再分配内存空间了,节省了时间和空间。
4. 普通方法
boolean |
booleanValue()
将此
Boolean 对象的值作为布尔原始值返回。 |
static int |
compare(boolean x, boolean y)
比较两个
boolean 值。 |
int |
compareTo(Boolean b)
将此
Boolean 实例与另一个实例进行比较。 |
boolean |
equals(Object obj)
返回
true 当且仅当参数不是 null ,并且是一个 Boolean 对象,表示与此对象相同的 boolean 值。 |
static boolean |
getBoolean(String name)
返回
true 当且仅当由参数命名的系统属性存在且等于字符串 "true" 。 |
int |
hashCode()
返回此
Boolean 对象的哈希码。 |
static int |
hashCode(boolean value)
返回一个
boolean 值的哈希码; 兼容Boolean.hashCode() 。 |
static boolean |
logicalAnd(boolean a, boolean b)
返回将逻辑AND运算符应用于指定的
boolean 操作数的结果。 |
static boolean |
logicalOr(boolean a, boolean b)
返回将逻辑OR运算符应用于指定的
boolean 操作数的结果。 |
static boolean |
logicalXor(boolean a, boolean b)
返回将逻辑XOR运算符应用于指定的
boolean 操作数的结果。 |
static boolean |
parseBoolean(String s)
将字符串参数解析为布尔值。
|
String |
toString()
返回一个
String 此布尔值的 String 对象。 |
static String |
toString(boolean b)
返回一个
String 指定布尔值的 String 对象。 |
static Boolean |
valueOf(boolean b)
返回一个
Boolean 指定的 boolean 值的 Boolean 实例。 |
static Boolean |
valueOf(String s)
返回一个
Boolean ,其值由指定的字符串表示。 |
4.1. compare 和 compareTo
前面定义中我们已知,Boolean 对象是可以比较大小的(这个有些意外,平时开发中好像从来没有对布尔类型做过大小比较),那么到底是怎么一个比较规则呢?下面先看一下比较大代码:
public int compareTo(Boolean b) { return compare(this.value, b.value); } public static int compare(boolean x, boolean y) { return (x == y) ? 0 : (x ? 1 : -1); }
可以看出:对于 compareTo(Boolean b) 方法,当当前对象和参数b指定对象同为 true 或者同为 false 时,返回0;否则当当前对象值为 true 时返回 1;否则返回 -1。根据 comparable 接口的常规约定:@return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. 我们可以看出,java在对布尔值比较大小时认为 true > false(姑且可以这么解释以方便记忆 compareTo 方法的规则,现实中真假应该是没有大小之说的吧)
4.2. getBoolean
该方法尝试获取一个由参数指定的名称的布尔类型的系统属性值(详细的可以去了解 System 类),如果该属性不存在或者不是布尔类型(所谓布尔类型,就是忽略大小写的 “true” 或者 “false” 字符串),都会返回 false;否则返回该系统属性的布尔值。代码:
* If there is no property with the specified name, or if the specified * name is empty or null, then {@code false} is returned. * * @param name the system property name. * @return the {@code boolean} value of the system property. * @throws SecurityException for the same reasons as * {@link System#getProperty(String) System.getProperty} * @see java.lang.System#getProperty(java.lang.String) * @see java.lang.System#getProperty(java.lang.String, java.lang.String) */ public static boolean getBoolean(String name) { boolean result = false; try { result = parseBoolean(System.getProperty(name)); } catch (IllegalArgumentException | NullPointerException e) { } return result; }
4.3. hashCode 方法
hashCode 是顶级类 Object 定义的基础方法之一,Boolean 对该方法进行了重写。该方法只可能返回 1231 和 1237 两个值。既然布尔只有两种值,那么 hashCode 也只有两个值,理所当然,顺理成章。(如果想问为什么偏偏是这两个数的朋友们就去了解一下 hashCode 方法设计的初衷和哈希表吧)
/** * Returns a hash code for this {@code Boolean} object. * * @return the integer {@code 1231} if this object represents * {@code true}; returns the integer {@code 1237} if this * object represents {@code false}. */ @Override public int hashCode() { return Boolean.hashCode(value); } /** * Returns a hash code for a {@code boolean} value; compatible with * {@code Boolean.hashCode()}. * * @param value the value to hash * @return a hash code value for a {@code boolean} value. * @since 1.8 */ public static int hashCode(boolean value) { return value ? 1231 : 1237; }
4.4. equals 方法
Boolean 类也重写了 equals 方法,当且仅当参数指定的对象也是 Boolean 实例且与当前对象真假值相同时返回 true。
public boolean equals(Object obj) { if (obj instanceof Boolean) { return value == ((Boolean)obj).booleanValue(); } return false; }
很显然,Boolean 对象遵循 hashCode 和 equals 方法的常规约定。
5. 划重点
5.1. Boolean 是最终类,不可被继承;
5.2. 构造 Boolean 对象,建议使用静态工厂方法 valueOf ,而不是构造方法(因为 valueOf 使用静态缓存),这样比较节省时间和空间;
5.3. Boolean 实现了 comparable 接口,可以比较大小,java 默认为 true> false;
5.4. Boolean 的 hashCode() 方法返回 1231(true 时)或 1237(false 时),且与 equals 方法遵循常规约定;