2012-03-03 13 views
6

La especificación de lenguaje Java establece que los escapes dentro de las cadenas son los C "normales" como \n y \t, pero también especifican escapes octales de \0 a \377. En concreto, el JLS dice:¿Por qué Java octal escapes solo sube a 255?

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 

lo que significa que algo así como \4715 es ilegal, a pesar de estar dentro del rango de un personaje de Java (Java desde personajes no son bytes).

¿Por qué Java tiene esta restricción arbitraria? ¿Cómo se supone que especifique códigos octales para caracteres más allá de 255?

+1

255 es el límite ASCII básico si no me equivoco, entonces tienes uno para cada personaje base ASCII. ¿No deberías estar feliz con eso? La razón por la que no puede ir, digamos \ 4715 es simplemente porque es más de 255, que es el límite ASCII estándar = D (no puedo explicar, consulte el contestador) –

+1

@Shingetsu: el límite ASCII es 127, no 255 . _Bytes_ están limitados a 255, a menos que estés hablando de bytes de Java que, por alguna razón extraña, están firmados :-) Pero los caracteres de Java no son bytes. – paxdiablo

+0

[Ver también] (http://stackoverflow.com/questions/3537706/howto-unescape-a-java-string-literal-in-java/4298836) –

Respuesta

9

Es probablemente por razones puramente históricas de que Java admite secuencias de escape octal en absoluto. Estas secuencias de escape se originaron en C (o quizás en los predecesores B y BCPL), en los días en que computadoras como la PDP-7 gobernaban la Tierra, y mucha programación se hacía en ensamblaje o directamente en código máquina, y octal era el número preferido base para escribir códigos de instrucción, y no había Unicode, solo ASCII, por lo que tres dígitos octales eran suficientes para representar el conjunto de caracteres completo.

Para cuando llegaron Unicode y Java, octal prácticamente había dado paso a hexadecimal como la base numérica preferida cuando el decimal simplemente no funcionaba. Así que Java tiene su secuencia de escape \u que toma dígitos hexadecimales. La secuencia de escape octal probablemente solo fue compatible para hacer que los programadores C estuvieran cómodos, y para facilitar la copia de las constantes de cadena de los programas C a los programas Java.

visita estos links para trivia histórica:

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

+1

+1 También tenga en cuenta que, aparte de escribir códigos de instrucción, octal es mucho más fácil que hexadecimal cuando trabaja (por ejemplo) una arquitectura con palabras de 36 bits y caracteres de 9 bits: 12 dígitos octales muestran exactamente una máquina palabra, con 3 dígitos para cada personaje. Si representas la misma palabra de 36 bits con 9 dígitos hexadecimales, no podrás distinguir fácilmente el valor de los caracteres individuales. –

+0

Como explica mi respuesta a continuación, las secuencias de escape \ uXXXX y octal se analizan en etapas muy diferentes. Una secuencia de escape \ uXXXX NO es una versión extendida de la secuencia de escape octal de C. Simplemente ponga una \ u000A en una cadena, y su programa dejará de compilar. – Sven

1

Si puedo entender las reglas (por favor, corríjanme si me equivoco):

\ 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, \\ no caen bajo las reglas OctalEscape; deben estar bajo reglas de carácter de escape separadas.

decimal 255 es igual a octal 377 (usar calculadora de Windows en modo científico para confirmar)

Por lo tanto un valor octal de tres dígitos cae en el rango de \000 (0) a \377 (255)

Por lo tanto, \4715 no es un valor octal válido ya que es una regla de más de tres dígitos octales. Si desea acceder al carácter de punto de código con el valor decimal 4715, use el símbolo de escape Unicode \u para representar el carácter UTF-16 \u126B (4715 en forma decimal) ya que cada Java char está en Unicode UTF-16.

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

The char data type (and therefore the value that a Character object encapsulates) are based on the original Unicode specification, which defined characters as fixed-width 16-bit entities. The Unicode standard has since been changed to allow for characters whose representation requires more than 16 bits. The range of legal code points is now U+0000 to U+10FFFF, known as Unicode scalar value. (Refer to the definition of the U+n notation in the Unicode standard.)

The set of characters from U+0000 to U+FFFF is sometimes referred to as the Basic Multilingual Plane (BMP). Characters whose code points are greater than U+FFFF are called supplementary characters. The Java 2 platform uses the UTF-16 representation in char arrays and in the String and StringBuffer classes. In this representation, supplementary characters are represented as a pair of char values, the first from the high-surrogates range, (\uD800-\uDBFF), the second from the low-surrogates range (\uDC00-\uDFFF).

Editado:

Cualquier cosa que más allá del valor octal válido del rango de 8 bits (más grande que un byte) es específico del idioma. Algunos lenguajes de programación pueden continuar para coincidir con la implementación de Unicode; algunos pueden no (limitarlo a un byte). Java definitivamente no lo permite aunque tiene soporte Unicode.

Unos pocos lenguajes de programación (Vendor-dependiente) de ese límite a de un byte literales octales:

  1. Java (todos los proveedores): - una constante entera octal que comienza con 0 o de un solo dígito en base-8 (hasta 0377); \ 0 a \ 7, \ 00 a \ 77, \ 000 a \ 377 (en formato literal de cadena octal)
  2. C/C++ (Microsoft) - Constante de entero entero que comienza con 0 (hasta 0377); formato literal de cadena octal \nnn
  3. Ruby: constante entera de octal que comienza con 0 (hasta 0377); cadena octal formato literal \nnn

Unos pocos lenguajes de programación (proveedor-dependiente) que soportan literales octales más grande que la de un byte:

  1. Perl - Una constante de entero octal que comienza con 0 ; cadena octal formato literal \nnn Ver http://search.cpan.org/~jesse/perl-5.12.1/pod/perlrebackslash.pod#Octal_escapes

Unos pocos lenguajes de programación no soportan literales octales:

  1. C# - usar Convert.ToInt32(integer, 8) para la base-8 How can we convert binary number into its octal number using c#?
+0

Sí, ya sé los límites.Mi pregunta no es cuáles son los límites, sino más bien _por qué_ esos límites están ahí, dado que los caracteres Java no están limitados al rango 0-255. Voy a aclarar la pregunta. – paxdiablo

+0

Por supuesto, Java está utilizando Unicode de 16 bits de ancho para 'String' y' char'. Pero ahora, está utilizando el símbolo escape '\' y lo usa para representar un valor octal que solo permite hasta '\ 377' en formato de escape octal Java o 255 en valor decimal. El formato de escape octal Java '\ 4715' no es un formato de escape octal válido porque tiene más de tres dígitos según las reglas de OctalEscape en JLS. – ecle

+0

Si desea acceder a más de 255 puntos de código en Unicode UTF-16 String/char, use el símbolo Unicode '\ u'. Entonces, para el código del punto 4715 (?) Es '\ u4715' (la forma correcta, creo que debería ser' \ u126B' para el decimal 4715) – ecle

0

El \ 0- \ 377 escapes octales también se heredan de C, y la restricción hace que una buena cantidad de sentido en una lengua como C donde los caracteres == bytes (al menos en los días felices antes de wchar_t).

1

La respuesta real a la pregunta "Por qué" requerirá que le preguntemos a los diseñadores de lenguaje Java. No estamos en condiciones de hacerlo, y dudo que incluso estén en condiciones de responder. (¿Puede usted recordar discusiones técnicas detalladas que tenía ~ hace 20 años?)

Sin embargo, una explicación plausible para esta "limitación" es que:

  • escapes octales fueron tomados de C/C++, en la que también están restringidos a 8 bits,
  • octal es pasado de moda , y la gente de TI generalmente prefiere y es más cómoda con hexadecimal, y
  • Java admite formas de expresar Unicode, incrustándolo directamente en el código fuente, o usando \u escapes Unicode ... que no están limitados a cadenas y caracteres literales.

Y para ser honesto, nunca he oído a nadie (aparte de usted) sostienen que los literales octales deben tener más de 8 bits en Java.


Por cierto, cuando empecé en el cálculo de los juegos de caracteres tendían a ser un hardware específico, y eran a menudo menos de 8 bits. En mis cursos de pregrado y mi primer trabajo después de graduarme, utilicé máquinas de la serie CDC 6000 que tenían palabras de 60 bits y un conjunto de caracteres de 6 bits: "Código de visualización", creo que lo llamamos. Octal funciona muy bien en este contexto. Pero a medida que la industria avanzó hacia la adopción (casi) universal de arquitecturas de 8/16/32/64 bits, las personas usaban cada vez más hexadecimal en lugar de octal.

0

No conozco ninguna razón por la cual los escapes octales están restringidos a los puntos de código Unicode 0 a 255. Esto podría ser por razones históricas. La pregunta básicamente quedará sin respuesta, ya que no había ninguna razón técnica para no aumentar el alcance de los escapes octales durante el diseño de Java.

Sin embargo, debe tenerse en cuenta que existe una diferencia no tan obvia entre los escapes Unicode y los escapes octales. Los escapes octales se procesan solo como parte de cadenas mientras que los escapes unicode pueden ocurrir en cualquier parte de un archivo, por ejemplo, como parte del nombre de una clase. También tenga en cuenta, que el siguiente ejemplo ni siquiera compilar:

String a = "\u000A"; 

La razón es, que \ u000A se expande a una nueva línea en una etapa muy temprana (básicamente al cargar el archivo). El siguiente código no genera un error:

String a = "\012"; 

la \ 012 se expande después el compilador ha analizado el código. Esto también se aplica a los otros escapes como \ n, \ r, \ t, etc.

Por lo tanto, en conclusión: los escapes Unicode NO son un reemplazo para los escapes octales. Ellos son un concepto completamente diferente. En particular, para evitar cualquier problema (como con \ u000A arriba), se debe usar el escape octal para los puntos de código 0 a 255 y escapes unicode para los puntos de código por encima de 255.

Cuestiones relacionadas