小白的消费为何被迫升级?-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 promotion
 char c = ‘\\u0001‘;
 a[c] = 1; // index expression promotion
 a[0] = -c; // unary - promotion
 System.out.println("a: " + a[0] + "," + a[1]);
 b = -1;
 int i = ~b; // bitwise complement promotion
 System.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

时间: 2024-10-16 16:48:05

小白的消费为何被迫升级?-java数据类型的转换的相关文章

Java数据类型的转换

Java数据类型的转换,基本类型的相互转换 1如何将字串 String 转换成整数 int? A. 有2个方法: 1). int i = Integer.parseInt([String]); 或 i = Integer.parseInt([String],[int radix]); 2). int i = Integer.valueOf(my_str).intValue(); 注: 字串转成 Double, Float, Long 的方法大同小异. 2 如何将整数 int 转换成字串 Stri

JAVA数据类型,变量,转换,常量,运算符

java数据类型: Java基本类型共有八种,基本类型可以分为三类: 1.字符类型char,用单引号赋值 2.布尔类型boolean 3.数值类型byte.short.int.long.float.double.数值类型又可以分为整数类型byte.short.int.long和浮点数类型float(直接赋值时必须在数字后加上f或F).double(赋值时可以加d或D也可以不加). java变量: 数据类型 变量名[=值][,变量名[=值]];int a;int b = 1;int c,d;int

Java数据类型的转换:隐式(自动)转换与强制转换

原文链接:http://java.chinaitlab.com/base/725590.html 简单数据类型之间的转换 简单数据类型由低到高(byte.short.char)< int < long < float< double 简单数据类型转换分为:低级到高级的自动转换:高级到低级的强制转换:包装类过渡类型能够转换: 自动类型转换:直接将低级类型只赋值给高级类型:如果低级类型为char型,向高级类型(整型)转换时,会转换为对应ASCII码值, 强制类型转换:高级类型赋值给低级

JAVA数据类型自动转换,与强制转换

一.数据类型自动转换 public class Test{ public static void main(String[] args){ int a = 1; double b = 1.5; double a_b_count = a+b; //整型与双精度型相加时,结果会自动转换为双精度型 String c = "凌"; char d = '晨'; char e = '好'; String c_d_e_content = c+d+e; //字符型与字符串型相加时,结果会自动转换为字符

Java学习笔记之:java数据类型的转换

package com.hgd.study; /** * 基本数据类型之间的转换 * @author HuTiger * */ public class DataTypeConversion { public static void main(String[] args) { } /** * 小类型向大类型的转换: * 完成的是自动转换,不许要程序员做相应的操作 * @param args */ public static void sTob() { byte b=100; System.out

JAVA基本数据类型及其转换

Java语言是一种强类型语言.这意味着每个变量都必须有一个声明好的类型.Java语言提供了八种基本类型.六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型.Java另外还提供大数字对象,但它不是Java的数据类型. 1.整数: 定义:没有小数部分的数字,负数是允许的. 种类:Java提供四种整数类型: byte 1个字节(8bit) -128到127(-27~27-1)  默认为0 ,如 byte b=28; short 2个字节(16bit) -32,768到32,767(-

java的数据类型的转换

一:java的数据类型转换除布尔类型boolean(不能转换)有两种:<一> 自动转换: <二> 强制转换 <一>.自动转换:就是将小的数据类型自动转换成大的数据类型.如:int与byte计算时,byte(-128~127)自动的转换成int(-2147483648~2147483647)的类型. 0.1.基本数据类型自动转换: byte->short,char -> int -> long float -> double int -> f

JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系

转载请注明出处:http://blog.csdn.net/xyang81/article/details/42047899 当我们在调用一个Java native方法的时候,方法中的参数是如何传递给C/C++本地函数中的呢?Java方法中的参数与C/C++函数中的参数,它们之间是怎么转换的呢?我猜你应该也有相关的疑虑吧,咱们先来看一个例子,还是以HelloWorld为例: HelloWorld.java: package com.study.jnilearn; class MyClass {}

Java数据类型

一.Java数据类型 1.基本数据类型 2.引用数据类型 二.基本数据类型   1.整数类型:bytr,short,int,long   2.浮点数据类型:float,double   3.字符类型:char   4.布尔类型:bollean 类型名称         字节空间             类型说明    byte          1字节(8位)       存储1个字节数据    short         2字节(16位)      兼容性考虑,一般不用    int