Java中布尔有两种:基本类型 boolean 和对象类型 Boolean。
打印基本类型 boolean
boolean value = false;
System.out.println(""+value);
System.out.println(String.format("%s", value));
System.out.println(String.format("%b", value));
上述代码,运行后输出:
false
false
false
对象类型 Boolean 的实现和常用方法
Boolean 类对 boolean 做了一层封装,类中设置了一个字段存放boolean值:
// 摘自 Java 8 源码
private final boolean value;
以下几种形式都是 true 对应的Boolean:
System.out.println(Boolean.TRUE);
System.out.println(new Boolean(true));
System.out.println(new Boolean("true"));
System.out.println(Boolean.valueOf(true));
System.out.println(Boolean.parseBoolean("true"));
上述代码,运行后输出:
true
true
true
true
true
既然是类,那么就要用 equals 判等,而不能用 ==
:
Boolean a = new Boolean(true);
Boolean b = new Boolean(true);
System.out.println(a == b); // 错误,会输出 false
System.out.println(a.equals(b)); // 正确
System.out.println(Objects.equals(a, b)); // 正确
上述代码,运行后输出:
false
true
true
既然是类,那么它还有一个值,即 null:
Boolean val = null;
System.out.println(val);
上述代码,运行后输出:
null
装箱与拆箱
Java 在处理 boolean 和 Boolean 时,会自动进行隐式的转换。
基本类型和对象类型之间判等:
System.out.println(true == Boolean.TRUE); // Boolean.TRUE 拆箱为 true
System.out.println(Boolean.TRUE.equals(true)); // true 装箱为 Boolean.parseBoolean(true)
上述代码,运行后输出:
true
true
若 Boolean 类型变量值为 null,是不能拆箱成 boolean的,会报 NPE:
Boolean val = null;
boolean val2 = val;
System.out.println(val2); // NullPointerException
上述代码,运行后输出:
java.lang.NullPointerException
at .....
同样的,下面的代码也会抛出 NPE 异常:
Boolean val = null;
if(val) {
System.out.println("Hi"); // NullPointerException
}
最常见的自动装箱,是函数参数/返回值是某种类型,但实际使用时用的是另外一个类型。
例如对于下面的函数:
public boolean negative(boolean val) {
return !val;
}
运行下面的代码:
System.out.println(negative(false));
System.out.println(negative(Boolean.FALSE));
输出:
true
true
什么时候不会自动装箱/拆箱
void process(boolean val) {
System.out.println("boolean");
}
@Test
public void test() {
process(true);
process(Boolean.TRUE); // 会自动拆箱
}
执行以上代码会输出:
boolean
boolean
但若是以下代码则不会发生自动拆箱,因为优先匹配符合要求的函数:
void process(boolean val) {
System.out.println("boolean");
}
void process(Boolean val) {
System.out.println("Boolean");
}
@Test
public void test() {
process(true);
process(Boolean.TRUE);
}
执行以上代码会输出:
boolean
Boolean
boolean 和 Boolean 之间的显式转换
将 boolean 转换为 Boolean 的常见方式是:
Boolean val = Boolean.valueOf(true);
将 Boolean 转换为 boolean 的常见方式是:
boolean val = Boolean.TRUE.booleanValue();
自动拆箱/装箱会增加耗时
看下面的代码示例:
int sum(int a, int b) {
return a + b;
}
Integer sum2(Integer a, Integer b) {
return a + b;
}
@Test
public void test() {
long start;
int result;
result = 0;
start = System.currentTimeMillis();
for(int i=0; i<100000; ++i) {
result = sum(result, i);
}
System.out.println(System.currentTimeMillis() - start); // 输出sum耗时
result = 0;
start = System.currentTimeMillis();
for(int i=0; i<100000; ++i) {
result = sum2(result, i);
}
System.out.println(System.currentTimeMillis() - start); //输出sum2耗时
}
多次运行后会发现,sum2的耗时是sum的2倍以上。为什么,因为 sum2 有自动装箱和拆箱操作。