小白的消费为何被迫升级?-java数据类型的转换
背景
小白最近有点烦恼,原因也很简单,不知道为何?小白的消费不知不觉被迫升级了,请看费用清单:
for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) {if (b == 0x90)System.out.print("life is Happy!");}
本来小白预期输出结果:
life is Happy!
但是什么都没有输出,这是怎么回事呢?是不是以后的幸福小日子就没了?
于是小白向柯南请教:
破案
为了比较byte 数值(byte)0x90 和int 数值0x90,Java 通过拓宽原始类型转换
将byte 提升为一个int[JLS 5.1.2],然后比较这两个int 数值。0x90为144,但byte指的范围为-128~127
故没有打印出预期的值。
究根到底
原来java language Specification中有自动Promotion机制,让我们了解一下数字提升的问题吧
数字提升总体的规则是向上提升,又分为一元数字提升和二元数字提升
一元数字提升
某些运算符将一元数值提升用在了单操作数运算中,其必定能得到一个数字类型的值,
规则如下:
if 操作数是编译时包装类型Byte、Short、Character或Integer,那么它会先拆箱为对应的原始类型,然后拓宽为int类型。
else if 操作数为编译时包装类型Long、Float或Double,那么就直接拆箱为对应的原始类型。
else if 操作数是编译时拆箱类型byte、short、char或int,那么就拓宽为int类型。
else 保持原样。
一元数值提升还用在以下情境的表达式中:
数组创建表达式的维度
数组索引表达式的索引
正号运算符(+)的操作数
负号运算符(-)的操作数
按位补运算符(~)的操作数
移位运算符(>>, >>>, << )的每一个操作数。注意移位运算并不会使两边的操作数提升到相同类型,如 A << B 中若B为long类型,A并不会被提升到long。
是不是很难理解?
那就举个例子吧
class Test {public static void main(String[] args) {byte b = 2;int a[] = new int[b]; // dimension expression promotionchar c = '\\u0001';a[c] = 1; // index expression promotiona[0] = -c; // unary - promotionSystem.out.println("a: " + a[0] + "," + a[1]);b = -1;int i = ~b; // bitwise complement promotionSystem.out.println("~0x" + Integer.toHexString(b)+ "==0x" + Integer.toHexString(i));i = b << 4L; // shift promotion (left operand)System.out.println("0x" + Integer.toHexString(b)+ "<<4L==0x" + Integer.toHexString(i));} }
输出结果为:
a: -1,1~0xffffffff==0x00xffffffff<<4L==0xfffffff0
二元数字提升
当二元运算符的操作数皆可转化为数字类型时,那么将采用如下二元数值提升规则:
如果任一操作数为引用类型,那么对其进行自动拆箱。
拓宽类型转换被应用于以下情况:
if 某一操作数为double类型,那么另一个也转为double
else if 某一操作数为float类型,那么另一个也转为float
else if 某一操作数为long类型,那么另一个也转为long
else 两个操作数都转为int
应用场景
- 乘除法运算符: * 、 / 、%
- 针对数字类型的加减运算符: + 、 -
- 数值比较运算符:< 、<= 、> 、>=
- 数值相等比较运算符: == 、 !=
- 整数按位运算符: & 、^ 、|
- 某些情况下的条件运算符 ? : 中
来个例子吧
class Test {public static void main(String[] args) {int i = 0;float f = 1.0f;double d = 2.0;// First int*float is promoted to float*float, then// float==double is promoted to double==double:if (i * f == d) System.out.println("oops");// A char&byte is promoted to int&int:byte b = 0x1f;char c = 'G';int control = c & b;System.out.println(Integer.toHexString(control));// Here int:float is promoted to float:float:f = (b==0) ? i : 4.0f;System.out.println(1.0/f);} }
其实上面的都是冰山一角罢了
更多信息可以查看jls Chapter 5. Conversions and Contexts
参考资料
【1】https://docs.oracle.com/javase/specs/jls/se12/html/jls-5.html#jls-5.1.2
转载于:https://www.cnblogs.com/davidwang456/p/11515979.html
小白的消费为何被迫升级?-java数据类型的转换相关推荐
- java 类型转换原理_9.java数据类型的转换
java数据类型的转换 Java中可以进行不同数据类型的加减乘除运算吗?是可以的.在算术运算符中已经体验过如果两个整数(int)相除会去掉小数部分.如果需要保留小数部分,可以让除数或者被除数变为dou ...
- JAVA 数据类型强制转换详解
JAVA 数据类型转换(强制类型转换) 强制类型转换 将 取值范围大的类型 强制转换成 取值范围小的类型 特点 : 代码需要进行特殊的格式处理, 不能自动完成 转换格式 // 范围小的类型 范围小的变 ...
- JAVA数据类型与转换
一.注释 注释是对代码进行解释说明的文字. 注释分类: //单行注释/* 多行注释 *//** 文档注释 */ 注意: 单行注释只在当前行有效且不可嵌套,通常用于解释一行的代码. 多行注释可在多行有效 ...
- JAVA数据类型的转换及数据的原反补三码
一.自动类型转换/隐式转换 规律一:小的类型自动转化为大的类型 short s = 7; long l = s; long l = 500; // 500是一个整数,整数默认为int,int的范围比l ...
- java数据类型的转换函数_JAVA中常用数据类型转换函数
JAVA中常用数据类型转换函数: string->byte Byte static byte parseByte(String s) byte->string Byte static St ...
- java 类之间转换,java数据类型之间转换应用方法
当一个对象不能直接类型转换.就需要造型. 例如: 一个int型能直接转换为double ,就不需要造型. 一个double型不能直接转换为int,就需要造型. int a =1 ; d ...
- java数据类型转化_JAVA基本数据类型及其转换
Java语言是一种强类型语言.这意味着每个变量都必须有一个声明好的类型.Java语言提供了八种基本类型.六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型.Java另外还提供大数字对 ...
- 小议JAVA数据类型间的相互转换
原作地址:http://fanqiang.chinaunix.net/program/java/2006-06-30/4727.shtml 一些初学JAVA的朋友可能会遇到JAVA的数据类型之间转换的 ...
- java数据类型_JAVA的数据类型
什么是数据类型:百度百科 数据类型在数据结构中的定义是一个值的集合以及定义在这个值集上的一组操作(简单来说就java对数据进行了分类,存在不同的类型) 那么为什么需要数据分类呢? 因为在java中不同 ...
最新文章
- C++之头文件与源文件
- 黄金的商品属性,货币属性,金融属性
- vue --- 使用animate.css实现动画
- 基于Java+SpringBoot+vue+element实现前后端分离蛋糕商城系统详细设计
- 深入了解Kubernetes REST API的工作方式
- 2019年的web前端领域
- 企业发展如何启动云的力量
- inline,block 和 inline-block 的区别
- 【CodeVS】 p1696 奇怪的函数
- SSIS包生成注意事项
- 《Objective-C函数速查实例手册》——导读
- 2套后台模板HTML+整套Easyui皮肤组件-后台管理系统模板
- 【正点原子STM32连载】第十章 STM32CubeMX简介 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1
- linux驱动开发架构
- 寻找协调器FindCoordinatorRequest请求流程
- (已解决)网页不显示数学公式||只显示源码
- IDEA 运行时出现 too long 异常
- 用python编写一个点餐程序_急急急!求大神帮忙做个Python在线点餐小软件
- 爆笑囧人囧事 2009 大合集!
- 【车间调度】模拟退火算法求解车间调度(jobshop-3)问题【含Matlab源码 1082期】