Java 学习笔记

所有文章
📖 最新文章 transmittable-thread-local 库 JOOR 反射库 Lombok 库:为你减少样板代码 Slf4j 日志组件的使用 加速maven、gradle依赖下载
📖 Java 基础 安装 第一个程序 使用 UTF-8 编写代码 空值 null 正则表达式 线程 日期/时间 匿名类 枚举 ThreadLocal 线程本地变量 动态代理 jar 命令

Java 布尔类型


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 异常:

java 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 有自动装箱和拆箱操作。


( 本文完 )

文章目录