为什么Java八进制转义只能达到255?

时间:2012-03-03 03:00:22

标签: java escaping octal

Java语言规范声明字符串内的转义符是\n\t之类的“普通”C语言,但它们也指定从\0到{{1}的八进制转义符}。具体而言,JLS声明:

\377

意味着像OctalEscape: \ OctalDigit \ OctalDigit OctalDigit \ ZeroToThree OctalDigit OctalDigit OctalDigit: one of 0 1 2 3 4 5 6 7 ZeroToThree: one of 0 1 2 3 这样的东西是非法的,尽管它在Java字符的范围内(因为Java字符不是字节)。

为什么Java有这种任意限制?你是如何指定超过255的字符的八进制代码?

4 个答案:

答案 0 :(得分:9)

由于纯粹的历史原因,Java可能完全支持八进制转义序列。这些逃逸序列起源于C(或者可能是C的前身B和BCPL),在像PDP-7这样的计算机统治地球的时代,大量编程是在汇编或直接在机器代码中完成的,而八进制是首选的数字写入指令代码的基础,没有Unicode,只有ASCII,所以三个八进制数字足以代表整个字符集。

当Unicode和Java出现时,八进制几乎已经让位于十六进制作为十进制时的首选数字基数。所以Java的\u转义序列采用十六进制数字。可能只支持八进制转义序列以使C程序员感到舒服,并且可以很容易地将C程序中的字符串常量复制到Java程序中。

查看这些链接了解历史琐事:

http://en.wikipedia.org/wiki/Octal#In_computers
http://en.wikipedia.org/wiki/PDP-11_architecture#Memory_management

答案 1 :(得分:1)

如果我能理解规则(如果我错了请纠正我):

\ OctalDigit
Examples:
    \0, \1, \2, \3, \4, \5, \6, \7

\ OctalDigit OctalDigit
Examples:
    \00, \07, \17, \27, \37, \47, \57, \67, \77

\ ZeroToThree OctalDigit OctalDigit
Examples:
    \000, \177, \277, \367,\377

\t\n\\不属于OctalEscape规则;它们必须遵循单独的逃避字符规则。

十进制255等于八进制377(在科学模式下使用Windows计算器确认)

因此,三位数的八进制值落在\000(0)到\377(255)的范围内

因此,\4715不是有效的八进制值,因为它超过三个八位数的规则。如果要访问具有十进制值4715的代码点字符,请使用Unicode转义符号\u来表示UTF-16字符\u126B(十进制形式为4715),因为每个Java char都是在Unicode UTF-16中。

来自http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Character.html

  

char数据类型(因此是Character对象的值   encapsulates)基于原始的Unicode规范   将字符定义为固定宽度的16位实体。 Unicode   从那时起,标准被改为允许其角色   表示需要超过16位。法律代码的范围   点现在是U + 0000到U + 10FFFF,称为Unicode标量值。   (请参阅Unicode标准中U + n表示法的定义。)

     

有时会引用从U + 0000到U + FFFF的字符集   作为基本多语言平面(BMP)。代码指向的字符   大于U + FFFF被称为补充字符。 Java   2平台使用char数组和中的UTF-16表示   String和StringBuffer类。在此表示中,补充   字符表示为一对char值,第一个来自   高代理范围,(\ uD800- \ uDBFF),第二个来自   低代理范围(\ uDC00- \ uDFFF)。

<强>编辑:

超出8位范围(大于一个字节)的有效八进制值的任何内容都是特定于语言的。一些编程语言可以继续匹配Unicode实现;有些可能不会(将其限制为一个字节)。 Java肯定不允许它,即使它有Unicode支持。

一些编程语言(依赖于供应商)限制为一字节八进制文字

  1. Java(所有供应商): - 一个八进制整数常量,以0或单个数字开头,以base-8(最多0377)为单位; \ 0到\ 7,\ 00到\ 77,\ 000到\ 377(八进制字符串文字格式)
  2. C / C ++(Microsoft) - 一个八进制整数常量,以0开头(最多0377);八进制字符串文字格式\nnn
  3. Ruby - 一个八进制整数常量,以0开头(最多0377);八进制字符串文字格式\nnn
  4. 一些编程语言(依赖于供应商)支持大于一个字节的八进制文字

    1. Perl - 以0开头的八进制整数常量;八进制字符串文字格式\nnn请参阅http://search.cpan.org/~jesse/perl-5.12.1/pod/perlrebackslash.pod#Octal_escapes
    2. 一些编程语言不支持八进制文字

      1. C# - 将Convert.ToInt32(integer, 8)用于base-8 How can we convert binary number into its octal number using c#?

答案 2 :(得分:1)

“为什么”这个问题的真正答案需要我们向Java语言设计师提问。我们无法做到这一点,我怀疑他们甚至可以回答这个问题。 (可以还记得你20年前的详细技术讨论吗?)

然而,对这种“限制”的合理解释是:

  • 八进制转义是从C / C ++中借来的,其中它们也被限制为8位,
  • 八进制是老式的,IT人员通常更喜欢十六进制,并且
  • Java支持表达Unicode的方式,可以通过将其直接嵌入源代码中,也可以使用\u Unicode转义符...不仅限于字符串和字符文字。

说实话,我从来没有听过任何人(除了你)认为八进制文字应该在Java中长于8位。


顺便提一下,当我开始计算字符集时,往往是硬件特定的,并且通常小于 8位。在我的本科课程和毕业后的第一份工作中,我使用了具有60位字和6位字符集的CDC 6000系列机器 - “显示代码”我认为我们称之为。 Octal在这种情况下非常好用。但随着行业向(几乎)普遍采用8/16/32/64位架构迈进,人们越来越多地使用十六进制而不是八进制。

答案 3 :(得分:0)

\ 0- \ 377八进制转义也是从C继承的,并且该限制在C语言中有相当大的意义,其中字符==字节(至少在wchar_t之前的数天)。