Los problemas del conjunto de caracteres son confusos y complicados por sí mismos, pero además de eso, debe recordar los nombres exactos de sus conjuntos de caracteres. ¿Es "utf8"
? O "utf-8"
? O tal vez "UTF-8"
? Al buscar muestras de código en Internet, verá todo lo anterior. ¿Por qué no simplemente hacerlos constantes con nombre y usar Charset.UTF8
?Java: ¿Por qué los nombres de los conjuntos de caracteres no son constantes?
Respuesta
La respuesta simple a la pregunta es que las cadenas de juegos disponibles varían de una plataforma a otra.
Sin embargo, hay seis que se requieren para estar presentes, por lo que las constantes podrían haberse hecho hace mucho tiempo. No sé por qué no lo fueron.
JDK 1.4 hizo algo genial al introducir el tipo de Charset. En este punto, ya no habrían querido proporcionar constantes String, ya que el objetivo es lograr que todos usen instancias Charset. Entonces, ¿por qué no proporcionar las seis constantes estándar de Charset? Le pregunté a Martin Buchholz, ya que él estaba sentado a mi lado, y me dijo que no había una razón particularmente importante, excepto que en ese momento, las cosas aún estaban medio cocidas: muy pocas API de JDK habían sido adaptadas para acepta Charset, y de los que sí lo fueron, las sobrecargas de Charset solían tener un peor rendimiento.
Es triste que solo en el JDK 1.6 hayan acabado de equipar todo con sobrecargas de Charset. Y que esta situación de rendimiento hacia atrás todavía existe (la razón por la cual es increíblemente raro y no puedo explicarlo, ¡pero está relacionado con la seguridad!).
Relativamente corto: simplemente defina sus propias constantes, o utilice la clase de Conjuntos de Guava a la que Tony el Pony se vinculó (aunque esa biblioteca realmente no se haya lanzado todavía).
Actualización: una clase StandardCharsets
está en JDK 7.
Simplemente curioso, ¿alguna idea de cuándo habrá un lanzamiento (alfa/beta/lo que sea) de guayaba? La página de inicio del proyecto es un poco cortante en esto. – Jonik
¡No hay pavo para mí hasta que salga! –
* la razón por la que es increíblemente raro y no puedo explicarlo, pero está relacionado con la seguridad *: puede crear una cadena modificable a través de conjuntos de caracteres personalizados, sin embargo, podrían haberse realizado incluso más rápido que la cadena (que realmente busca el juego de caracteres). Es una omisión/negligencia cómo se implementa 'String (byte bytes [], int offset, int length, Charset charset)'. De hecho, el golpe de rendimiento no es para nada trivial cuando se crea una pequeña cadena de un byte grande []. – bestsss
Argumentaría que podemos hacer mucho mejor que eso ... ¿por qué no se puede acceder directamente a los conjuntos de caracteres garantizados? Charset.UTF8
debe ser una referencia al Charset
, no el nombre como una cadena. De esa forma no tendríamos que manejar UnsupportedEncodingException
por todo el lugar.
Tenga en cuenta que también creo que .NET eligió una mejor estrategia por defecto a UTF-8 en todas partes. Se enrosca entonces por nombrar el "defecto del sistema operativo" codificación de la propiedad simplemente Encoding.Default
- lo cual no es al impago en .NET sí :(
Volver a despotricar sobre el apoyo conjunto de caracteres de Java - por qué no hay un constructor ? para FileWriter
/FileReader
que toma un Charset
Básicamente esas son las clases casi inútil debido a que la restricción - casi siempre se necesita un InputStreamReader
alrededor de un FileInputStream
o el equivalente para la salida :(
enfermera, enfermera -? ¿dónde está mi medicina
EDITAR: Se me ocurre que esto no ha respondido realmente a la pregunta. La respuesta real es presumiblemente "nadie pensó en ello" o "alguien involucrado pensó que era una mala idea". Sugiero encarecidamente que las clases de utilidad interna que proporcionan los nombres o conjuntos de caracteres eviten la duplicación en la base del código ... O simplemente podría usar the one that we use at Google.
+1. Pero como un método en lugar de un campo para permitir la carga diferida (está bien, es probable que desee UTF-8, pero hay algunos otros conjuntos de caracteres y es posible que desee instalaciones similares para ellos). Desafortunadamente, esto no parece ser muy popular entre los que toman las decisiones. –
Estaría contento con un método, aunque espero que cargar ansiosamente esos pocos conjuntos no suponga un gasto significativo. –
Estamos en una cruzada para detener la ardua carga de clases./Acabo de buscar un JDK para "UTF-8". Encontrados 270 resultado (s) en 165 archivo (s).Aunque mucho de eso está en la basura vieja de Apache (creo que contribuido por mi equipo). –
El estado actual de la API de codificación deja algo que desear.Algunas partes de la API de Java 6 no aceptan Charset
en lugar de una cadena (en logging
, dom.ls
, PrintStream
; puede haber otras). No ayuda que las codificaciones se supone que tienen diferentes nombres canónicos para diferentes partes de la biblioteca estándar.
Entiendo cómo llegaron las cosas a su ubicación; no estoy seguro de tener ideas brillantes sobre cómo solucionarlos.
Como acotación al margen ...
Puede buscar los nombres de ejecución Java 6 here del solar.
Para UTF-8, los valores canónicas son "UTF-8"
para java.nio
y "UTF8"
para java.lang
y java.io
. Las únicas codificaciones que la especificación requiere que admita JRE son: US-ASCII; ISO-8859-1; UTF-8; UTF-16BE; UTF-16LE; UTF-16.
No me molesta el PrintStream, ya que la clase dice claramente "La clase PrintWriter debe usarse en situaciones que requieren escribir caracteres en lugar de bytes." (Que es, como, todas las situaciones ...) –
Hace mucho tiempo definí una clase de utilidad con las constantes UTF_8, ISO_8859_1 y US_ASCII Charset.
Además, hace algún tiempo (2+ años) me hizo una prueba de rendimiento simple entre new String(byte[], Charset)
y new String(byte[], String charset_name)
y descubrió que esta última aplicación es CONSIDERABLEMENTE más rápido. Si echas un vistazo debajo del capó en el código fuente, verás que de hecho siguen un camino bastante diferente.
Por esa razón por la que incluyó una utilidad de la misma clase
public static String stringFromByteArray (
final byte[] array,
final Charset charset
)
{
try
{
return new String(array, charset.name())
}
catch (UnsupportedEncodingException ex)
{
// cannot happen
}
}
Por qué la cadena (byte [], juego de caracteres) constructor no haga lo mismo, me pega.
El 'Charset' no necesita ser registrado, por lo que la excepción puede ocurrir. IIRC, hubo algunos cambios en JDK7 para hacerlo más rápido para las implementaciones conocidas de' Charset' (eliminar la copia extra). –
Dos años más tarde, y en Java 7 StandardCharsets ahora se definen constantes para los 6 conjuntos de caracteres estándar.
Si está atascado en Java 5/6, puede usar las constantes de Charsets de Guava, según lo sugerido por Kevin Bourrillion y Jon Skeet.
En Java 1,7
import java.nio.charset.StandardCharsets
ejemplo: StandardCharsets.UTF_8
StandardCharsets.US_ASCII
- 1. ¿Por qué los conjuntos de Python no son lavables?
- 2. ¿Cuáles son los caracteres válidos para los nombres de macro?
- 3. ¿Cuáles son los caracteres legales/permitidos para los nombres de los archivos del servidor web?
- 4. ¿Por qué Java no ve que los enteros son iguales?
- 5. ¿Los valores de propiedad son siempre constantes?
- 6. ¿Por qué las direcciones de función no son expresiones constantes?
- 7. ¿Por qué necesitamos conjuntos de caracteres UCS y Unicode?
- 8. ¿Por qué los EJB son seguros y los servlets no?
- 9. ¿Por qué los nombres de argumento de función no son importantes en las declaraciones de C++?
- 10. Conjuntos de cadenas constantes
- 11. ¿Por qué Java no tiene constantes para nombres de propiedades de sistemas bien conocidos?
- 12. ¿Por qué los nombres de atributos no son palabras clave de Python?
- 13. ¿Por qué los prototipos de funciones incluyen nombres de parámetros cuando no son necesarios?
- 14. ¿Qué son los conjuntos uno al lado del otro?
- 15. Caracteres no alfanuméricos en los nombres de interfaz COM/.NET
- 16. ¿Qué caracteres son ampliamente compatibles con los nombres de clases de CSS?
- 17. ¿Los constructores de Java no son públicos por defecto?
- 18. ¿Por qué los nombres de usuario no se pueden cambiar?
- 19. Extraiga los nombres de los textos (Java)
- 20. ¿Qué caracteres debo escapar/desinfectar para los nombres de archivo?
- 21. conjuntos de caracteres - no está claro
- 22. ¿Por qué los nombres de archivo de diseño de Android son tan limitados?
- 23. HTTP URL - caracteres permitidos en los nombres de los parámetros
- 24. ¿Por qué son los caracteres @, $,: y; ¿Caracteres reservados en un componente de consulta url?
- 25. ¿Qué son los nombres de archivo reservados para varias plataformas?
- 26. ¿Por qué los objetos Joda son inmutables?
- 27. ¿Para qué son los espacios de nombres XML?
- 28. ¿Por qué los nombres de imagen de proceso a veces se rellenan con caracteres hexadecimales?
- 29. PHP/MySQL - Los caracteres seguros para mostrar los nombres/nombres de usuario/contraseñas, con DOP
- 30. ¿Por qué los repositorios de datos no son estáticos?
+1: Esto también me estaba molestando todo el tiempo. La misma historia continúa para 'MessageDigest # getInstance()' por cierto. – BalusC
Para la respuesta real, necesitarías preguntarle a alguien en Sun. Buena suerte con eso :-) –
Stephen C: Creo que ha sido discutido en una lista de correo pública. Alguien en Sun. –