从int到char和ASCII值的类型转换

时间:2014-09-07 10:46:00

标签: java

int a1 = 65535;

char ch2 = (char) a1;

System.out.println("ASCII value corresponding to 65535 after being typecasted : "+ch2);// prints?
char ch3 = 65535;
System.out.println("ASCII value corresponding to 65535 : "+ch3);// again prints?

我引用Herbert Schildt的第3章:数据类型,变量和数组:

  

char的范围是0到65535.没有负的字符。该   称为ASCII的标准字符集范围仍为0到127   与往常一样,扩展的8位字符集ISO-Latin-1范围   从0到255.由于Java旨在允许编写程序   对于全球使用,它有意义使用Unicode   代表人物。     只要在范围内,整数也可以分配给char。

//char ch33 = 65536; compilation-error, ofcourse since out of char range (which is 0 - 65535)

int a11 = 65536;  
  char ch22 = (char) a11;   
System.out.println("ASCII value corresponding to 65536 after being typecasted : "+ch22);
  // non-printing character(appearance of a small square like figure in eclipse console)

问题是:为什么此行的没有编译错误:char ch22 = (char) a11,即使char ch33 = 65536不起作用?还有一件事,当int a1 = 65535被采取时,情况并非如此?

3 个答案:

答案 0 :(得分:2)

好的,那里有几个截然不同的问题。

我认为第一个问题是:

为什么看到?当您输出ch2ch3

因为您输出的是无效字符。 Java字符represent UTF-16 code points,而不是实际字符。 UTF-16中的某些Unicode字符需要两个 Java char来存储。有关UTF-16 here in the Unicode FAQ的更多信息。在UTF-16中,值0xFFFF(您的ch2ch3包含的值)无效作为独立值;即使它是,也没有Unicode U+FFFF character

重新计算ch22的输出:您看到一个小方框的原因是您输出了字符0(char)65536的结果为0,见下文),这是一个“控制字符”(32以下的所有字符 - 正常空格字符 - 是各种控制字符)。字符0是“空”字符,因为我没有普遍接受的字形。

为什么在执行int a11 = 65536; char ch22 = (char) a11;时没有错误?

因为这就是Java narrowing primitive conversions的定义方式。没有错误;相反,只使用相关的位:

  

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

答案 1 :(得分:0)

关于char ch22 = (char) a11工作的原因

From java specification

  

缩小的原始转换可能会丢失有关数值整体幅度的信息,也可能会失去精度和范围。

     

[...]

     

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


关于char c = 65536无效

的原因

From java specification

  

如果是,则可以使用缩小的基元转换,然后进行装箱转换   变量的类型是:

     
      
  • 字节和常量表达式的值可以在字节类型中表示。
  •   
  • 简短,常量表达式的值可在short类型中表示。
  •   
  • 字符和常量表达式的值可在char。
  • 类型中表示   

65536本身并不是char值

例如

  • 1同时是byte,short,char,int和long值。
  • 256是short,char,int和long值,但不是字节值。
  • 65535是char,int和long值,但既不是字节也不是短值。
  • -1是一个byte,short,int,long值,但不是char值。
  • 65536只是一个int和long值。

char c = (char)65536;将有效

答案 2 :(得分:0)

Java char类型包含Unicode / UTF-16代码单元,其中一个或两个代码点对代码点进行编码。并非所有16位正整数都是有效的代码单元。而且,由于您要处理char而不是String,因此您希望将值限制为仅使用一个代码单元编码的代码点。

65535不是有效的UTF-16代码单元,也不是有效的Unicode代码点。

关于你的问题,为什么你没有得到例外,我只能与其他类似整数的操作进行比较,在这些操作中你不会因溢出和类似的异常结果而获得异常。语言因设计妥协而有所不同。

我提交,如果您使用charCharacterString以正确的方式做正确的事,您将不会遇到问题像这样。忘记" ASCII仍然一如既往地从0到127,以及扩展的8位字符集,ISO-Latin-1。" Java使用Unicode;拥抱它。