缩小转换是将可以容纳较大值的数据类型放入可以容纳较小值的数据类型。
long l = 4L;
int i = (int)l;
但是我不明白为什么短到 char 是一种缩小转换,但我直觉它与这两种数据类型的有符号/无符号相关,但我无法解释原因。
short s = 4; // short max value is 32767
char c = (char)s; // char max value is 65535
看起来这将是一个扩大转换,或者至少既不缩小也不扩大,因为它们都是 16 位并且可以保存相同数量的值。
System.out.println((int)Character.MIN_VALUE); //0
System.out.println((int)Character.MAX_VALUE); //65535
System.out.println(Short.MIN_VALUE); //-32768
System.out.println(Short.MAX_VALUE); //32767
//65535 = 32768+32767
这是因为
short
能够保持负值,而 char
则不能,正如您可能从 Character.MIN_VALUE
中看到的那样。让我举几个例子。
short s = -124;
char c = 124; // OK, no compile time error
char d = -124; // NOT OK, compile time error since char cannot hold -ve values
char e = s; // NOT OK, compile time error since a short might have -ve values which char won't be able to hold
char f = (char)s; // OK, type casting. The negative number -124 gets converted to 65412 so that char can hold it
System.out.println((short)f); // -124, gets converted back to a number short can hold because short won't be able to hold 65412
System.out.println((int)f); // 65412, gets converted to 65412 because int can easily hold it.
一个(负)数
-n
,当转换为 char
时,变成 2^16-n
。所以,-124
变成了2^16-124 = 65412
。
缩小的重点不是位大小,而是某些值无法在新类型中正确表示。
正如您在最后一段代码中所示,
Short.MIN_VALUE < Character.MIN_VALUE
,即某些short
值无法用char
表示。
由于您无法使用
char
忠实地表示负数(强制转换将导致负数由其 2 的补码表示,这不是同一个数字),因此我们认为强制转换“丢失了信息”,从而缩小了范围.
来自 Java 语言规范,§5.1.3:
基元类型上的 22 种特定转换称为窄化基元转换:
至short
或byte
char
至char
或byte
short
- ...
缩小原始转换可能会丢失有关数值总体大小的信息,并且还可能丢失精度和范围。
...
有符号整数到整型类型的缩小转换
只是丢弃除 n 最低阶位之外的所有位,其中 n 是用于表示类型T
的位数。 除了可能丢失有关数值大小的信息之外,这还可能导致结果值的符号与输入值的符号不同。T
将
缩小转换为整型char
同样简单地丢弃除 n 最低阶位之外的所有位,其中 n 是用于表示类型T
的位数。除了可能丢失有关数值大小的信息之外,这还可能导致结果值为负数,即使字符表示 16 位无符号整数值。T