您的位置 首页 java

技 术 | 你不知道的Java—05.多重转型

技 术 | 你不知道的Java—05.多重转型

转型被用来将一个数值从一种类型转换到另一种类型。下面的程序连续使用了三个转型。那么它到底会打印出什么呢?

技 术 | 你不知道的Java—05.多重转型

无论你怎样分析这个程序,都会感到很迷惑。它以 int 数值-1 开始,然后从 int 转型为 byte,之后转型为 char ,最后转型回 int。第一个转型将数值从 32 位窄 化到了 8 位,第二个转型将数值从 8 位拓宽到了 16 位,最后一个转型又将数值 从 16 位拓宽回了 32 位。这个数值最终是回到了起点吗?如果你运行该程序,你就会发现不是。

它打印出来的是 65535,但是这是为什么呢?

该程序的行为紧密依赖于转型的符号扩展行为。 Java 使用了基于 2 的补码的二 进制运算,因此 int 类型的数值-1 的所有 32 位都是置位的。从 int 到 byte 的 转型是很简单的,它执行了一个 窄化原始类型转化(narrowing primitive conversion) ,直接将除低 8 位之外的所有位全部砍掉。这样做留下的是一个 8 位都被置位了的 byte,它仍旧表示-1。

从 byte 到 char 的转型稍微麻烦一点,因为 byte 是一个有符号类型,而 char 是一个无符号类型。在将一个整数类型转换成另一个宽度更宽的整数类型时,通常是可以保持其数值的,但是却不可能将一个负的 byte 数值表示成一个 char。

因此,从 byte 到 char 的转换被认为不是一个拓宽原始类型的转换,而是一个 拓宽并窄化原始类型的转换(widening and narrowing primitive conversion) :byte 被转换成了 int,而这个 int 又被转换成了 char。

所有这些听起来有点复杂,幸运的是,有一条很简单的规则能够描述从较窄的整型转换成较宽的整型时的符号扩展行为:如果最初的数值类型是有符号的,那么就执行符号扩展;如果它是 char,那么不管它将要被转换成什么类型,都执行零扩展。了解这条规则可以使我们很容易地解决这个问题。

因为 byte 是一个有符号的类型,所以在将 byte 数值-1 转换成 char 时,会发生符号扩展。作为结果的 char 数值的 16 个位就都被置位了,因此它等于 216-1,即 65535。从 char 到 int 的转型也是一个拓宽原始类型转换,所以这条规则告诉我们,它将执行零扩展而不是符号扩展。作为结果的 int 数值也就成了 65535,这正是程序打印出的结果。

尽管这条简单的规则描述了在有符号和无符号整型之间进行拓宽原始类型时的符号扩展行为,你最好还是不要编写出依赖于它的程序。如果你正在执行一个转型到 char 或从 char 转型的拓宽原始类型转换,并且这个 char 是仅有的无符号整型,那么你最好将你的意图明确地表达出来。

如果你在将一个 char 数值 c 转型为一个宽度更宽的类型,并且你不希望有符号扩展,那么为清晰表达意图,可以考虑使用一个位掩码,即使它并不是必需的:

int i = c & 0xffff;

或者,书写一句注释来描述转换的行为:

int i = c; //不会执行符号扩展

如果你在将一个 char 数值 c 转型为一个宽度更宽的整型,并且你希望有符号扩展,那么就先将 char 转型为一个 short ,它与 char 具有同样的宽度,但是它是有符号的。在给出了这种细微的代码之后,你应该也为它书写一句注释:

int i = (short) c; //转型将引起符号扩展

如果你在将一个 byte 数值 b 转型为一个 char,并且你不希望有符号扩展,那么你必须使用一个位掩码来限制它。这是一种通用做法,所以不需要任何注释: char c = (char) (b & 0xff);

这个教训很简单:如果你通过观察不能确定程序将要做什么,那么它做的就很有可能不是你想要的。

要为明白清晰地表达你的意图而努力。尽管有这么一条简单的规则,描述了涉及有符号和无符号整型拓宽转换的符号扩展行为,但是大多数程序员都不知道它。如果你的程序依赖于它,那么你就应该把你的意图表达清楚。

更多技术干货欢迎关注公众号:格睿泰思

采编排:左 左

文章来源:智云一二三科技

文章标题:技 术 | 你不知道的Java—05.多重转型

文章地址:https://www.zhihuclub.com/191289.shtml

关于作者: 智云科技

热门文章

发表回复

您的电子邮箱地址不会被公开。

2条评论

  1. Serious Use Alternative 1 verapamil will increase the level or effect of entrectinib by affecting hepatic intestinal enzyme CYP3A4 metabolism

  2. Even With Metastatic Breast Cancer, Some Patients Should Say No to Surgery and Radiation 91 United States v

网站地图