【问题标题】:Why is casting to short to char is a narrowing conversion?为什么将转换为short to char 是一种缩小转换?
【发布时间】:2016-06-13 05:44:49
【问题描述】:

缩小转换是将可以容纳较大值的数据类型转换为最大可以容纳较小值的数据类型。

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

【问题讨论】:

  • 你不能用char表示负数。

标签: java casting


【解决方案1】:

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

当转换为char 时,一个(负)数-n 变为2^16-n。所以,-124 变成了
2^16-124 = 65412

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    缩小的重点不在于位大小,而在于某些值无法在新类型中正确表示。

    正如您在最后一段代码中所示,Short.MIN_VALUE < Character.MIN_VALUE,即某些short 值无法在char 中表示。

    由于您不能使用char 忠实地表示负数(转换将导致负数由其 2 的补码表示,这不是同一个数字),我们认为转换“丢失信息”并且从而缩小。

    来自Java Language Specification, §5.1.3

    对原始类型的 22 种特定转换称为窄化原始转换:

    • shortbytechar
    • charbyteshort
    • ...

    窄化基元转换可能会丢失有关数值整体大小的信息,也可能会丢失精度和范围。

    ...

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-30
      • 2015-01-20
      • 2017-08-17
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多