1. 业奇农业网 > 百科 >

boomen怎么通关

走进 JDK 之 Boolean

boomen怎么通关

路遥

来自专栏走进 JDK

往期目录:

走进 JDK 之 Integer

走进 JDK 之 Long

走进 JDK 之 Float

走进 JDK 之 Byte

今天来说说 Boolean 。Boolean 类源码也很简单,在阅读源码的过程中思考这么一个问题,Boolean 类型在内存中是如何表示的?或者说,JVM 是如何看待 Boolean 的?

类声明

public final class Boolean implements java.io.Serializable,Comparable<Boolean>

Boolean 也是不可变类,事实上所有的基本类型包装类、String、BigDecimal、BigInteger 也都是不可变类。

字段

private final boolean value;

public static final Boolean TRUE = new Boolean(true); // true

public static final Boolean FALSE = new Boolean(false); // false

public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean");

private static final long serialVersionUID = -3665804199014368530L;

Boolean 类型只有两个值,true 和 false。

构造函数

public Boolean(boolean value) {

this.value = value;

}

public Boolean(String s) {

this(parseBoolean(s));

}

还是熟悉的味道,第一个构造函数直接传入 boolean。第二个构造函数调用 parseBoolean() 方法,将 String 转换为布尔值。

方法

parseBoolean()

public static boolean parseBoolean(String s) {

return ((s != null) && s.equalsIgnoreCase("true"));

}

直接和字符串 true 进行比较。

valueOf()

public static Boolean valueOf(boolean b) {

return (b ? TRUE : FALSE);

}

public static Boolean valueOf(String s) {

return parseBoolean(s) ? TRUE : FALSE;

}

toString()

public static String toString(boolean b) {

return b ? "true" : "false";

}

hashcode()

public static int hashCode(boolean value) {

return value ? 1231 : 1237;

}

源代码都很简单,没有什么好说的。回过头看看文章开头的问题:

JVM 是怎么处理 Boolean 的 ?

源码中貌似也看不出什么端倪,我们得从 Java 虚拟机的角度出发了。先看下面这个例子:

public class BooleanTest {

public void test() {

boolean flag = true;

if (flag)

System.out.println("This is true.");

}

}

test 方法显然会打印字符串 This is true。站在人脑的思维很容易理解,下面我们站在 JVM 的思维来看一下该如何理解。

首先虚拟机肯定是不认识这些源代码的,它认识的只有字节码,也就是 class 文件。关于 Class 文件的具体格式,可以看看我之前的一篇文章,Class 文件格式详解。我在这就直接使用 javap 命令来查看字节码了。

javac BooleanTest.java

javap -v BooleanTest.class

略去常量池等部分内容,我把 test() 方法的字节码内容拿过来:

public void test();

descriptor: ()V // 方法描述符

flags: ACC_PUBLIC // 访问标志

Code:

stack=2, locals=2, args_size=1

0: iconst_1

1: istore_1

2: iload_1

3: ifeq 14

6: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;

9: ldc #3 // String This is true.

11: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

14: return

下面逐行分析 Code 部分:

stack=2, locals=2, args_size=1

stack 表示操作数栈深度的最大值,这里是 2 。locals 表示局部变量表所需的存储空间,这里需要两个 slot。还记得什么是 slot 吗,slot 是虚拟机为局部变量分配内存所使用的最小单位。args_size 是参数个数,这里 test() 方法并没有参数,但是每个方法都有一个参数是指向当前引用自身的。

0: iconst_1 // 将一个 int 常量 1 加载到操作数栈

1: istore_1 // 将数值 1 从操作数栈存储到局部变量表

2: iload_1 // 将局部变量 1 加载到操作数栈

这三行字节码其实就是 boolean flag = true; 。JVM 并没有为 boolean 专门做处理,而是直接当做 int处理。true 就是 1, false 就是 0 。

3: ifeq 14

...

14: return

ifeq 是控制转移指令,这里的含义是如果操作数栈上的值是 0, 就跳转到 14 处,14 处指令为 return,则结束方法执行。这里已经将 1 加载到操作数栈,所以会继续往下执行,省略号中的字节码内容就是打印语言 System.out.println("This is true.");,不作过多分析。

根据 Java 虚拟机规范,JVM 并没有任何供 boolean 值专用的字节码指令,Java 源代码中使用到的布尔值,在编译之后都使用 int 值来代替。JVM 也支持 boolean 类型数组,其一般经过编译会被当作 byte 数组进行处理。所以,在字节码中,你是看不到 boolean 的。

还记得上篇文章 走进 JDK 之 Byte 中提出的一个问题,作为方法内部局部变量的 byte 在内存中占几个字节 ? 结论是:

基本类型作为方法局部变量是存储在栈帧上的,除了 long 和 double 占两个 Slot,其他都占用一个 Slot

在 JVM 的眼里,并没有这么多的数据类型,对于 boolean 、byte 、short 和 char,在编译期都会变成 int 类型,JVM 也仅仅只对 int 提供了最完整的操作码,其他类型数据的操作,都是使用相应的 int 类型的操作码进行操作。那么 JVM 为什么没有给每种数据类型都配置完整的操作码呢?这还得从操作码的长度说起。

Java 虚拟机操作码的长度为一个字节,所以字节码指令集的操作码总数不可能超过 256 条。这么做是为了尽可能获得短小精干的字节码,字节码指令流都是单字节对齐的,数据量小,传输效率高。当然,这么做的代价就是你不可能设计出一套面向所有数据类型都完整的操作码。如果每一种数据结构都要得到 Java 虚拟机的字节码指令的支持的话,那么指令的数量将远远超过 256 种。所以,这也给指令集的设计带来了麻烦。最终权衡的结果就是,只对有限的类型提供完整的指令。大部分的指令都没有支持 byte 、 char 和 short,boolean 则更惨,没有任何指令支持 boolean 类型。对于这些不支持的指令类型,一律使用 int 的相关指令代替。

总结

Boolean 其实是被当做 int 值处理的,true 表示 1,false 表示 0

JVM 为 int 提供了完善的操作码,boolean 、byte 、char 、short 在编译期或运行期都会被转换为 int,使用 int 类型的字节码指令进行处理

文章同步更新于微信公众号: 秉心说 , 专注 Java 、 Android 原创知识分享,LeetCode 题解,欢迎关注!

![]

展开阅读全文

明日方舟畸变体怎么打畸变体打法攻略

Boom Beach海岛奇兵新手玩家第一次进游戏对于界面还不熟习。我就给小伙伴们详细介绍下。多多关注我偶们Boom Beach海岛奇兵,会有更多精彩内容呈现。

我们的海岛界面

界面介绍

图中 A 标志是显示玩家等级,等级越高遇到的敌人就越高。 图中 B 标志是玩家勋章数,玩家每打败一个NPC或者玩家海岛时就会得到相应的勋章奖励。 图中 C 标志是建筑按钮,点击进去可以看到你所能建造的建筑。 图中 D 标志是建筑可以摆放的区域,后面的树林是可以砍伐的,不过前期可别急着去砍。 图中 E 标志是大地图按钮,就是可以进去大地图界面。 图中 F 标志是资源和钻石显示区域,金币、木材、钢铁等资源,以及充值获得的钻石。 图中 G 标志是系统按钮包括成就、排行榜、系统设置三个功能。 图中 H 标志是码头,停放着运送船和战舰,我们攻打NPC和玩家的主要工具。 大地图界面

界面介绍

图中 A 标志是我们海岛在地图上的标志,点击可以进入海岛。 图中 B 标志是NPC的资源岛,这个是随机刷新的。 图中 C 标志是玩家的海岛,可以互相攻打。 图中 D 标志是已经攻占的资源岛,可以提供木材资源。 图中 E 标志是已经攻打的普通海岛,可以提供金币资源。 图中 F 标志是进入自己海岛按钮。

明日方舟畸变体怎么打畸变体打法攻略,相信很多小伙伴对这一块不太清楚,接下来小编就为大家介绍一下明日方舟畸变体怎么打畸变体打法攻略,有兴趣的小伙伴可以来了解一下哦。

畸变体打法攻略

一阶段,最好是血怒阿能,亲测技能7/7可打死。为什么要用阿能呢?因为阿能后期可以清左右一侧的小东西。

接下来是二阶段,用强输出,最好是银老板,因为群攻可以清一下小东西。在畸变体两边各下一个炸弹。

高输出的输出得多高呢,畸变体打不死炸弹就行。

二阶段无敌一过高输出就开技能,秒掉二阶段,打出三阶段。然后三阶段无敌一过立刻开炸弹。boom!畸变体剩一丝血。然后他就把自己烧死了。

小东西怎么清呢,实测,精二四十满信赖阿能可以两枪打死,精一55满信赖克洛丝三枪(都不用技能)

小东西非常脆,最好是用快狙(这里推荐蓝毒,虽然脆但是输出高。)

另外我的打法前期需要很高的费用支持,我带了桃子德狗推王凛冬(除了推王都专三了),费用勉强够。如果先锋不够的话会出现非常严重的卡费现象

本文由用户上传,如有侵权请联系删除!转转请注明出处:https://nongye.s666.cn/bk/6_6571836517.html