为什么将short类型强制转换成char类型是一种缩小转换?

6

缩小转换是指将一个能够容纳更大值的数据类型放入最多只能容纳较小值的数据类型中。

long l = 4L;
int i = (int)l;

然而,我不明白为什么将一个short转换为char是一种缩小转换,但我有直觉它与这两种数据类型的signed/unsigned有关,但我无法解释为什么。

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

1
你不能用 char 表示负数。 - kennytm
2个回答

8
这是因为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

希望这可以帮助您。


4
缩小类型的目的不在于位大小,而是某些值不能在新类型中正确表示。
如您在最后一段代码中所示,即 Short.MIN_VALUE < Character.MIN_VALUE ,即一些 short 值无法用 char 表示。
由于您不能使用 char 来忠实地表示负数(强制转换会导致负数被其二进制补码表示,这不是相同的数字),因此我们认为此转换“丢失了信息”,从而发生缩小。
来自Java语言规范第5.1.3节
引用:

22种原始类型之间的特定转换称为缩小原始转换:

  • shortbytechar
  • charbyteshort
  • ...

缩小原始转换可能会丢失关于数值总体大小的信息,并且还可能丢失精度和范围。

...

有符号整数到整数类型 T 的缩小转换只会丢失所有但 n 个低位,其中 n 是用于表示类型的位数。 除了可能丢失有关数字值大小的信息外,这可能会导致结果值的符号与输入值的符号不同。

char 到整数类型 T 的缩小转换同样只会丢弃除 n 个最低位之外的所有位,其中 n 是用于表示类型的位数。除了可能丢失有关数字值大小的信息外,这还可能导致结果值为负数,即使字符表示16位无符号整数值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接