匿名用户

1级

2016-08-29 回答

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

public class Multicast{

public static void main (String[] args){

System.out.println((int)(char)(byte) -1);

}

}

无论你怎样分析这个程序,都会感到很迷惑。它以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隐含转化_java中自动转换和强制转换还有隐含转换相关推荐

  1. java数据类型转化_JAVA基本数据类型及其转换

    Java语言是一种强类型语言.这意味着每个变量都必须有一个声明好的类型.Java语言提供了八种基本类型.六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型.Java另外还提供大数字对 ...

  2. java bufferedinputstream 编码_java中关于编码的问题(字符转换流及字符缓冲流 )

    上次我们使用的是字节流,还有一种方式就是字符流,上次说过如何分辨使用哪种流,如果记事本可以读懂则使用字符流,否则使用字节流.使用字符流就需要牵扯到编码的问题,下面给出一种转化流的格式. OutputS ...

  3. java 内部变量_java 中的内置数据类型

    1,  基本数据类型 Java是强类型语言, 对于每一种数据都定义了类型,基本数据类型分为数值型,字符型,布尔型.数值型又分为了整型和浮点型. 整型又分为byte, int, short long. ...

  4. java 数据类型分为_JAVA中分为基本数据类型及引用数据类型

    byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0 short:短整型,在内存中占16位,即2个字节,取值范围-32768~32717,默认值 ...

  5. java类索引_java中索引的分类,图片详解

    java的学习是一个漫长而又循环往复不断上升的过程,今天我们再来看一下java索引的分类,并且通过详细的图片解析. 首先,java中的索引主要分为聚簇索引和非聚簇索引. 其中InnoDB主键使用的是聚 ...

  6. java有道_java中的各种流(老师的有道云笔记)

    内存操作流-字节 之前的文件操作流是以文件的输入输出为主的,当输出的位置变成了内存,那么就称为内存操作流.此时得使用内存流完成内存的输入和输出操作. 如果程序运行过程中要产生一些临时文件,可采用虚拟文 ...

  7. java判断类型_Java中类型判断的几种方式 - 码农小胖哥 - 博客园

    1. 前言 在Java这种强类型语言中类型转换.类型判断是经常遇到的.今天就细数一下Java中类型判断的方法方式. 2. instanceof instanceof是Java的一个运算符,用来判断一个 ...

  8. java年份换算_java中日期的换算处理

    JAVA8中的日期API是JSR-310的实现,并且是工作在ISO-8601日历系统基础上的,但我们也可以在非ISO的日历上. JDK8的日期API大致分为以下几个包: 1 java.time包:JD ...

  9. java stringbuffer数组_Java中字符数组、String类、StringBuffer三者之间相互转换

    一.StringBuffer与String的相互转换 1.将StringBuffer转换成String StringBuffer类成员toString函数可将其转换成String类型. StringB ...

最新文章

  1. 数据仓库的未来 MariaDB ColumnStore
  2. 第一个以自己语言描述GBDT算法
  3. [改善Java代码]线程优先级只使用三个等级
  4. java基础学习总结一(java语言发展历史、jdk的下载安装以及配置环境变量)
  5. Trie 树——搜索关键词提示 1
  6. 世界公认最好的记忆方法_全球公认最好的12个教育孩子的方法,值得每个家长收藏学习!...
  7. 计算机网络之网络概述:2、标准化工作及其相关组织
  8. Data intensive Application (1)
  9. 15 张 Vim 速查表奉上,帮你提高N倍效率!
  10. 数学建模论文格式规范(国赛)
  11. 命令行解析工具gflags
  12. 「应用安全」应用安全原则
  13. ubuntu 右键选单没有创建文档
  14. 花窗图案c语言设计,4款中式仿古花窗图案隔断设计图 中式传统古建筑园林木门花窗艺术文化图片...
  15. Redis篇 <一>Docker安装redis 及基础
  16. Facebook广告投放:WC广告的优点和缺点
  17. 数据库之Timestamp 的用法
  18. 微信小程序购物商城定制开发
  19. swust oj代码+解析_1165,0284,0074,0042,1171,0026,0189,0078,0046,0077,0209,0129
  20. CLRS 17.3势能法

热门文章

  1. 修改SqlServer的登录密码
  2. Tomcat端口号的修改
  3. 【OpenCV 例程200篇】86. 频率域滤波应用:指纹图像处理
  4. php测试号推送消息失败,信息发送失败是什么原因
  5. d3.js 旋转图形_MATLAB 的图形处理
  6. 项目案例:在线拍卖系统_冀拓公司在张家口开展尾矿库在线监测监控系统 建设项目...
  7. python如何读取csv文件某几行某几列_关于python:读取.csv文件时,我似乎无法指定列dtypes...
  8. 详述白盒测试的逻辑覆盖的路径覆盖及其优缺点
  9. var let this的区别
  10. .net core consul 服务配置 服务发现 服务健康检测 服务变更加载