Problemy z zestawem znaków są mylące i skomplikowane, ale oprócz tego należy pamiętać dokładne nazwy swoich zestawów znaków. Czy to jest "utf8"
? Lub "utf-8"
? A może "UTF-8"
? Podczas wyszukiwania w Internecie dla próbek kodu zobaczysz wszystkie powyższe. Dlaczego po prostu nie uczynić ich nazwanymi stałymi i użyć Charset.UTF8
?Java: Dlaczego nazwy zestawów znaków nie są stałe?
Odpowiedz
Prostą odpowiedzią na zadane pytanie jest to, że dostępne ciągi znaków zestawów zależą od platformy.
Jednakże, istnieje sześć, które muszą być obecne, więc stałe mogły być wykonane dla tych, dawno temu. Nie wiem, dlaczego nie byli.
JDK 1.4 zrobił wielką rzecz, wprowadzając typ zestawu słuchawkowego. W tym momencie nie chcieliby już dostarczać stałych String, ponieważ celem jest, aby wszyscy korzystali z instancji Charset. Dlaczego więc nie podać sześciu standardowych stałych Charset? Poprosiłem Martin Buchholz skoro dzieje się siedzący obok mnie i powiedział, że nie było naprawdę szczególnie wielki powód, chyba, że w momencie, rzeczy wciąż połowiczne - zbyt mało JDK API została zmodernizowana do Akceptuj Charset, a tych, które były, przeciążenia Charset zwykle wykonywane nieco gorsze.
To smutne, że to tylko w JDK 1.6, że ostatecznie zakończył wyposażeniowych wszystko z przeciążeniami charset. I że nadal istnieje ta sytuacja wstecz wydajność (powód jest bardzo dziwne i nie potrafię tego wyjaśnić, ale jest związane z bezpieczeństwem!).
Krótko mówiąc - wystarczy zdefiniować własne stałe lub użyj guawy w klasę charsets który Tony Pony powiązany (mimo, że biblioteka nie jest jeszcze naprawdę faktycznie zwolniony).
Aktualizacja: klasa StandardCharsets
jest w JDK 7.
Po prostu ciekawy, jaki będzie pomysł, kiedy pojawi się wersja Guava (alfa/beta/cokolwiek)? Strona domowa projektu jest w tym przypadku nieco zawikłana. – Jonik
Żaden indyk dla mnie, dopóki go nie ma! –
* powód, dla którego jest niesamowicie dziwny i nie mogę tego wyjaśnić, ale jest związany z bezpieczeństwem * - możesz utworzyć modyfikowalny ciąg za pomocą niestandardowych zestawów znaków, ale mogłyby one zostać wykonane nawet szybciej niż ciąg (który faktycznie wyszukuje charset). To zaniedbanie/zaniedbanie jak zaimplementowano 'String (bajt bajtów [], int offset, int length, charset charset)'. W rzeczywistości trafienie wydajnościowe wcale nie jest trywialne podczas tworzenia małego ciągu z dużego bajtu []. – bestsss
Twierdzę, że możemy zrobić o wiele lepiej ... dlaczego nie mamy zagwarantowanych dostępnych zestawów znaków dostępnych bezpośrednio? Charset.UTF8
powinno być odniesieniem do Charset
, a nie nazwą w postaci ciągu. W ten sposób nie musielibyśmy obsługiwać UnsupportedEncodingException
w każdym miejscu.
Pamiętajcie, ja też uważam, że .NET wybrał lepszą strategię domyślnie wszędzie na UTF-8. Następnie wkręca się przez nazywanie „domyślny system operacyjny” kodowania własność prostu Encoding.Default
- co nie jest domyślny w samym .NET :(
Powrót do ranting o wsparcie charset Java - dlaczego nie jest konstruktorem ? o FileWriter
/FileReader
który zajmuje Charset
Zasadniczo te są niemal bezużyteczne zajęcia z powodu tego ograniczenia - prawie zawsze potrzebować InputStreamReader
wokół lub FileInputStream
odpowiednik dla wyjścia :(
pielęgniarka, pielęgniarka -
gdzie jest moje lekarstwo?EDYCJA: Wydaje mi się, że tak naprawdę nie odpowiedział na pytanie. Prawdziwą odpowiedzią jest przypuszczalnie albo "nikt o tym nie pomyślał", albo "ktoś zaangażowany myślał, że to zły pomysł". Zdecydowanie sugeruję, aby wewnętrzne klasy narzędziowe zawierające nazwy lub zestawy znaków unikały duplikowania kodu źródłowego ... Lub można po prostu użyć the one that we use at Google.
+1. Ale jako metoda, a nie pole, aby umożliwić leniwy ładowanie (dobrze, prawdopodobnie będziesz chciał UTF-8, ale istnieje kilka innych zestawów znaków i możesz chcieć podobnych udogodnień dla nich). Niestety wydaje się, że nie jest to zbyt popularne wśród podejmujących decyzje. –
Byłbym zadowolony z metody, aczkolwiek mam nadzieję, że szybkie ładowanie tych bardzo niewielkich zestawów znaków nie będzie znaczącym kosztem. –
Jesteśmy na krucjacie, aby zatrzymać szybkie ładowanie klas./Po prostu przeszukałem JDK dla "UTF-8". Znaleziono 270 wyników w 165 plikach.Chociaż wiele z tego jest w starych śmieciach Apache'a (moim zdaniem jest to zasługa mojego zespołu). –
Obecny stan API kodowania pozostawia wiele do życzenia.Niektóre części interfejsu API Java 6 nie akceptują Charset
w miejsce ciągu znaków (w logging
, dom.ls
, PrintStream
; mogą istnieć inne). Nie pomaga, aby kodowanie miało różne nazwy kanoniczne dla różnych części standardowej biblioteki.
Rozumiem, jak rzeczy się znalazły tam, gdzie są; nie jestem pewien, czy mam jakieś genialne pomysły, jak je naprawić.
Tak na marginesie ...
Można spojrzeć na nazwy dla Java 6 wdrażania Sun here.
UTF-8, wartości kanoniczne są "UTF-8"
do java.nio
i "UTF8"
do java.lang
i java.io
. Jedyne kodowania, które specyfikacja wymaga od JRE, to: US-ASCII; ISO-8859-1; UTF-8; UTF-16BE; UTF-16LE; UTF-16.
Nie żartuję z klasy PrintStream, ponieważ klasa wyraźnie mówi: "Klasa PrintWriter powinna być używana w sytuacjach wymagających pisania znaków, a nie bajtów." (Które jest, jak wszystkie sytuacje ...) –
Dawno temu zdefiniowałem klasę narzędzi o stałych znaków UTF_8, ISO_8859_1 i US_ASCII.
Również niektóre dawno temu (2+ lat) zrobiłem prosty test wydajności pomiędzy new String(byte[], Charset)
i new String(byte[], String charset_name)
i odkrył, że ta ostatnia realizacja jest ZNACZNIE szybciej. Jeśli spojrzysz pod maską kodu źródłowego, zobaczysz, że rzeczywiście podążają całkiem inną ścieżką.
Z tego powodu zawierał użyteczność w tej samej klasie
public static String stringFromByteArray (
final byte[] array,
final Charset charset
)
{
try
{
return new String(array, charset.name())
}
catch (UnsupportedEncodingException ex)
{
// cannot happen
}
}
Dlaczego String (byte [] Kodowanie) konstruktor nie to samo, bije mnie.
'Charset' nie musi być zarejestrowany, więc wyjątek może się zdarzyć .Irc, było kilka zmian w JDK7, aby uczynić go szybszym dla dobrze znanych implementacji' Charset' (wyeliminować dodatkowa kopia). –
Dwa lata później i Java 7's StandardCharsets definiuje teraz stałe dla 6 standardowych zestawów znaków.
Jeśli utkniesz na Java 5/6, możesz użyć stałych Guava Charsets, jak sugerują Kevin Bourrillion i Jon Skeet.
W Javie 1.7
import java.nio.charset.StandardCharsets
ex: StandardCharsets.UTF_8
StandardCharsets.US_ASCII
- 1. dlaczego stałe Java są zadeklarowane jako statyczne?
- 2. „Stałe ANSI” Java
- 3. Generowanie zestawów nie powiodło się - zestaw referencyjny nie ma silnej nazwy. Dlaczego inne rozwiązania nie działają?
- 4. zestaw zestawów znaków w szynach
- 5. Czy Java definiuje stałe dla dowolnych znaków, takich jak SPACJA?
- 6. Szablony i stałe ciągi znaków
- 7. Jak znaleźć nazwy zestawów reguł PMD w Gradle> 2.0
- 8. lokalne buforowanie Java stałe
- 9. Numery dopasowań nie są poprzedzone ciągiem znaków
- 10. Czy stałe statyczne funkcji inline są unikalne?
- 11. Jak zdefiniować statyczne stałe w wyliczeniu Java?
- 12. Stałe i właściwości w java
- 13. C++ Konwertowanie znaków na znaki stałe *
- 14. Gdzie mogę znaleźć stałe znaków w C#?
- 15. Dlaczego nie mogę używać znaku w pliku kodu źródłowego Java jako nazwy zmiennej?
- 16. Dlaczego inicjatory instancji Java są inicjowane?
- 17. Dlaczego blokady są Serializable w java?
- 18. Dlaczego stałe z rozszerzonego modułu nie są dostępne w metodach klas zadeklarowanych jako self?
- 19. Czy globalne stałe są anty-wzorcami?
- 20. Java: dlaczego Thread.sleep() i yield() są statyczne?
- 21. dlaczego java wnioskowanie nie
- 22. Generowanie zestawów nie powiodło się - zestaw referencyjny "Interop.Office" nie ma silnej nazwy
- 23. C# - czy wszystkie są stałe Enum?
- 24. Dlaczego FDT 5.5 nie znajduje moich zestawów SDK Flex?
- 25. Jakie są prawidłowe nazwy tabel w SQLite?
- 26. Dlaczego iteratory nie są kopiowalne?
- 27. UTF-8 znaków nie są wyświetlane poprawnie
- 28. Dlaczego nazwy nie-podkreślenia są zarezerwowane dla implementacji dla UDL, a nie na odwrót?
- 29. java read write unicode/UTF-8 nazwy plików (nie zawiera)
- 30. Nazwy zmiennych i kodowania znaków
+1: Zostało to również podsłuch mi cały czas. Ta sama historia dzieje się dla 'MessageDigest # getInstance()' przy okazji. – BalusC
Aby uzyskać prawdziwą odpowiedź, musisz zapytać kogoś w firmie Sun. Powodzenia w tym :-) –
Stephen C. Wierzę, że zostało to omówione na publicznej liście mailingowej. - Ktoś w Słońcu. –