Pourquoi charset noms ne sont pas des constantes?
Charset questions sont confus et compliqué par eux-mêmes, mais en plus de cela, vous devez vous rappeler nom exact de votre jeux de caractères. Est-il "utf8"
? Ou "utf-8"
? Ou peut-être "UTF-8"
? Lors de la recherche internet pour les exemples de code vous permettra de voir l'ensemble de la ci-dessus. Pourquoi ne pas simplement faire eux, nommé constantes et l'utilisation Charset.UTF8
?
- +1: C'était aussi m'énerve tout le temps. La même histoire se passe pendant
MessageDigest#getInstance()
par la voie. - Pour la vraie réponse, vous auriez besoin de demander à quelqu'un au coucher du Soleil. Bonne chance 🙂
- Stephen C: je crois qu'il a été discuté sur une liste de diffusion publique. -Quelqu'un au coucher du Soleil.
- voir cette question
Vous devez vous connecter pour publier un commentaire.
La réponse simple à la question posée, c'est que le disponible jeu de caractères les chaînes de varier d'une plateforme à une autre.
Cependant, il y en a six qui sont tenus d'être présents, de sorte que les constantes pourrait avoir été faite pour ceux qui il y a longtemps. Je ne sais pas pourquoi ils ne l'étaient pas.
JDK 1.4 a fait une grande chose, en introduisant le jeu de caractères de type. À ce stade, ils n'auraient pas voulu donner de constantes de Chaîne de plus, puisque le but est d'amener tout le monde à l'aide de Charset instances. Alors pourquoi ne pas fournir le six du jeu de caractères standard constantes, alors? J'ai demandé à Martin Buchholz car il lui arrive d'être assis à côté de moi, et il m'a dit il n'y avait pas vraiment particulièrement bonne raison, sauf que à l'époque, les choses étaient encore à moitié cuit-trop peu de JDK Api avait été rajoutée à accepter le jeu de caractères, et de ceux qui l'ont été, le jeu de caractères surcharges généralement effectuée légèrement pire.
Il est triste de constater que c'est seulement dans le JDK 1.6 qu'ils ont finalement fini d'équiper tout avec Charset les surcharges. Et que cette rétro performances situation existe encore (la raison en est incroyablement bizarre et je ne peux pas l'expliquer, mais est lié à la sécurité!).
Longue histoire courte -- il suffit de définir vos propres constantes, ou de l'utilisation de la Goyave de jeux de Caractères de la classe qui Tony le Poney lié à (si cette bibliothèque n'est pas vraiment en fait encore sorti).
Mise à jour: un
StandardCharsets
classe est dans le JDK 7.String(byte bytes[], int offset, int length, Charset charset)
est mis en œuvre. En fait, le gain de performance n'est pas trivial du tout lors de la création d'une petite chaîne à partir d'une grande byte[].Deux ans plus tard, et Java 7 StandardCharsets maintenant définit des constantes pour les 6 jeux de caractères standard.
Si vous êtes coincé sur Java 5/6, vous pouvez utiliser la Goyave est Les jeux de caractères constantes, comme suggéré par Kevin Bourrillion et Jon Skeet.
Je dirais que nous pouvons faire beaucoup mieux que ça... pourquoi ne pas la garantie-à-être-disponible jeux directement accessibles?
Charset.UTF8
doit être une référence à laCharset
, pas le nom d'une chaîne de caractères. De cette façon, nous n'aurions pas à gérerUnsupportedEncodingException
tous sur la place.Vous l'esprit, je pense aussi qu' .NET a choisi une meilleure stratégie par défaut UTF-8 partout. Il a ensuite vissé vers le haut, en nommant le "système d'exploitation par défaut" propriété de codage simplement
Encoding.Default
- qui n'est pas la valeur par défaut à l'intérieur .NET lui-même 🙁Retour à rodomontades sur Java de jeu de caractères de soutien - pourquoi n'est-il pas un constructeur de
FileWriter
/FileReader
qui prend unCharset
? Fondamentalement, ceux qui sont presque inutiles les cours en raison de cette restriction - vous presque toujours besoin d'unInputStreamReader
autour d'unFileInputStream
ou l'équivalent pour la sortie 🙁Infirmière, infirmière - où est mon médicament?
EDIT: Il me semble que cela n'a pas vraiment répondu à la question. La vraie réponse est sans doute soit "personne impliquée pensé" ou "quelqu'un qui pensait que c'était une mauvaise idée." Je suggère fortement que la maison de l'utilitaire de classes fournissant les noms ou les jeux de caractères d'éviter la duplication autour de la base de code... Ou vous pouvez simplement utiliser celui que nous avons utilisé à Google lorsque cette réponse a d'abord été écrit. (Notez qu'à partir de Java 7, vous devriez juste utiliser
StandardCharsets
à la place.)StandardCharsets
.static final
champ) ne cause pas de chargement de classe. Il n'a jamais été une raison pour utiliser un littéral"UTF-8"
en mille endroits au lieu d'un seul canonique symbole. Donc, c'est l'inverse, en utilisant une méthode qui serait en fait la cause de la classe de chargement lorsque la méthode est appelée.java.nio.file.Files
, y comprisnewBufferedReader
etnewBufferedWriter
, par défaut àUTF-8
lorsque aucuneCharset
a été fourni (et les méthodes qui prennent un charset nomString
n'existent même pas dans cette classe).StandardCharsets
obtient touché, leUTF_16LE
est chargé. (Qui va ralentir le RMI-CGI pont.)StandardCharsets
a été conçu. Après tout, il n'est pas nécessaire d'avoir distinctesUTF_16BE
,UTF_16LE
, etUTF_16
classes; c'est un vestige de l'époque où les jeux de caractères où recherché par la construction et de rechercher des noms de classe. Ces classes sont obsolètes; le travail est fait par leur classe de base commune. En fait, il n'y a aucun besoin pour les différentsCharset
la mise en œuvre des classes à tous, que la spécialisation qui se passe dans le décodeur et encodeur implémentations.En Java 1.7
import java.nio.charset.StandardCharsets
ex:
StandardCharsets.UTF_8
StandardCharsets.US_ASCII
L'état actuel de l'encodage de l'API laisse quelque peu à désirer. Certaines parties de la version 6 de Java API ne pas accepter
Charset
en place d'une chaîne de caractères (enlogging
,dom.ls
,PrintStream
; il peut y en avoir d'autres). Cela n'aide pas que les encodages sont censés avoir différents noms canoniques pour les différentes parties de la bibliothèque standard.Je peux comprendre comment les choses sont arrivés là où ils sont; pas sûr que j'ai des idées brillantes sur la façon de les corriger.
Que d'un côté...
Vous pouvez rechercher les noms de Sun Java 6 mise en œuvre ici.
Pour l'UTF-8, les canonique valeurs sont
"UTF-8"
pourjava.nio
et"UTF8"
pourjava.lang
etjava.io
. La seule codages de la spécification exige un JRE afin d'en charge sont: US-ASCII, ISO-8859-1; format UTF-8 ET UTF-16BE; UTF-16LE; UTF-16.J'ai il y a longtemps défini une classe utilitaire avec UTF_8, ISO_8859_1 et US_ASCII jeu de caractères constantes.
Aussi, certains depuis longtemps (+de 2 ans), j'ai fait un simple test de performance entre
new String( byte[], Charset )
etnew String( byte[], String charset_name )
et découvert que ce dernier mise en œuvre est CONSIDÉRABLEMENT plus rapide. Si vous prenez un coup d'oeil sous le capot au code source, vous verrez qu'ils sont, en effet, suivre un tout autre chemin.Pour cette raison, j'ai inclus un utilitaire dans la même classe
Pourquoi le String( byte[], Charset ) constructeur ne fait pas de même, ça me dépasse.
Charset
n'a pas besoin d'être enregistrées, de sorte que l'exception peut arriver. Autant que je me souvienne, il y avait quelques changements dans JDK7 pour le rendre plus rapide pour les bonnesCharset
implémentations (éliminer la copie supplémentaire).