由于业务发展关系,前段时间将一个风控平台从Ruby语言迁移到了Java平台,基于Spring进行了重构,写了一段时间Java后,本身发现居然还挺喜欢的(可能由于那段时间真的深深体会了 动态语言一时爽,重构火葬场 的玩笑)。因此后续决定阅读部分源码进行深刻提高Java水平,网上搜索了一番,看到了不少的推荐,例如Spring
框架的源码之类的,还有一些其余的开源组件项目,可是后面想一想仍是先从Java基础入手吧,因而就有了这篇文章,从最简单的Boolean开始。html
源代码基于 jdk1.8.0_181.jdk 版本。水平有限,第一次看相关代码,也第一次写😂若有建议和意见,欢迎联系指出。java
Java的Boolean
对象是对boolean
基本数据类型的封装,有着一个字段存放对应的boolean
数据值,提供了许多方法方便对boolean
进行操做。数组
public final class Boolean implements java.io.Serializable, Comparable<Boolean> 复制代码
由于带有final
关键字,也就是不可继承,另外实现了Serializable
和Comparable
接口,也就是能够进行序列化和比较的。oracle
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
复制代码
TRUE
和FALSE
定义了两个静态常量,表明着boolean
中的true
和false
。框架
@SuppressWarnings("unchecked")
public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean");
复制代码
获取类信息,Boolean.TYPE == boolean.class
二者是等价的。jvm
private final boolean value;
复制代码
Boolean
由于是boolean
的包装类,因此这里就是包含了对应的boolean基本类型的变量ide
private static final long serialVersionUID = -3665804199014368530L;
复制代码
public Boolean(boolean value) {
this.value = value;
}
public Boolean(String s) {
this(parseBoolean(s));
}
复制代码
存在两个构造方法,一个是传入boolean类型值,一个是传入字符串解析,而对应的解析方法以下:post
public static boolean parseBoolean(String s) {
return ((s != null) && s.equalsIgnoreCase("true"));
}
复制代码
这里就很直白的告诉了你,只有true
(忽略大小写)格式的字符串才会返回true
,其他的都为false
。这里本身所以还踩过坑,一直觉得字符串存在时就是真值,仍是和Ruby不同的。学习
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
public static Boolean valueOf(String s) {
return parseBoolean(s) ? TRUE : FALSE;
}
复制代码
咱们经过Boolean b = new Boolean(true);
时会得到一个新的实例对象,当你并不须要这个新实例而只要对应的值时,就应该采用这里的静态方法,直接返回了上面定义的静态变量,节省了一点内存又避免了建立一个新实例的时间开销。this
public boolean booleanValue() {
return value;
}
复制代码
获取对应的boolean类型值。
public static String toString(boolean b) {
return b ? "true" : "false";
}
public String toString() {
return value ? "true" : "false";
}
复制代码
返回对应布尔值的String对象。若是为true
则返回"true"字符串,不然就是"false"。
@Override
public int hashCode() {
return Boolean.hashCode(value);
}
public static int hashCode(boolean value) {
return value ? 1231 : 1237;
}
复制代码
其中重写了hashcode
方法,返回值调用了静态方法hashcode
,而静态方法返回值:当true
时返回1231,false
返回1237。这里颇有意思的是这两个固定的数字,很好奇为何是这两个值,因此网上搜索了下,有两篇回答能够参考一下。
大体意思是,主要这两个是较大的质数(实际上其余较大的质数也能够),至于较大质数的缘由是能够有效减小Hash碰撞冲突的发生。而Boolean是一个很经常使用的对象,会常常在其余里面使用,这么作有助于提高效率。
public boolean equals(Object obj) {
if (obj instanceof Boolean) {
return value == ((Boolean)obj).booleanValue();
}
return false;
}
复制代码
首先判断传入的obj
是否是Boolean
的实例,而后比较二者的值是否相等。从这里能够发现,若是咱们习惯于在判断前增长if (null == obj)
的逻辑,其实在这里是能够忽略的,由于null
确定不是Boolean
的实例,会直接返回false
。
public static boolean getBoolean(String name) {
boolean result = false;
try {
result = parseBoolean(System.getProperty(name));
} catch (IllegalArgumentException | NullPointerException e) {
}
return result;
}
复制代码
从代码上看,这个方法并非将输入字符串转换成boolean
类型的方法。而是当且仅当 系统属性 中存在着对应名称的属性,且它的值为“true”(忽略大小写)时,返回true
类型,不然返回false
。
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);
}
复制代码
比较两个Boolean实例对象或者boolean类型值,当相等时,返回0;不然根据第一个值进行判断,第一个值为true
时返回1,不然返回-1。
public static boolean logicalAnd(boolean a, boolean b) {
return a && b;
}
public static boolean logicalOr(boolean a, boolean b) {
return a || b;
}
public static boolean logicalXor(boolean a, boolean b) {
return a ^ b;
}
复制代码
提供了三个静态方法,对于两个boolean
类型值进行与、或、异或操做,返回对应的判断结果值。
在看代码的过程当中,想知道boolean究竟是个啥东西,而后去看了下 oracle 的官方文档,忽然学到了一点小知识,顺带记录一下。
在Java的八种基本数据类型中,除了boolean
其它7种都有明确的字节数长度,只有boolean
没有给出具体的字节数长度定义,详细的介绍以下:
boolean: The
boolean
data type has only two possible values:true
andfalse
. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its "size" isn't something that's precisely defined.
boolean
只存在true
和false
两个值,这个数据类型也是用于跟踪真/假条件的简单标志。这个数据类型表明了1bit的信息,可是它的大小并无明确的定义。由此搜索了一下,发现具体的应该是由Java虚拟机规范定义的。官方的文档 Java Virtual Machine Specification 有这个相关的说明,boolean
类型值会被编译使用int
类型进行替换,也就是4字节的大小;而boolean
类型数组,jvm并非直接支持的,而是经过byte[]
实现,其中也就是占用1字节。具体的说明能够查看提供的原文连接,也是很是有意思的信息。
总体的源代码是很简单的,可是此次查看源码的过程当中也学到了不少的东西,平时一些可能彻底不会关注的点,在此次过程当中也都学习到了,例若有些状况下应该使用Boolean.valueOf(true)
替换new Boolean(true)
,hashCode
的值,boolean
的相关文档定义等等,魔鬼藏在细节里,继续加油。