Именованное отображение между последовательностями шестнадцатиразрядных элементов кода Unicode и последовательностями байтов. Этот класс определяет методы для того, чтобы создать декодеры и кодеры и для того, чтобы получить различные имена, связанные с набором символов. Экземпляры этого класса являются неизменными.
Этот класс также определяет статические методы для того, чтобы протестировать, поддерживается ли определенный набор символов, для того, чтобы определить местоположение экземпляров набора символов по имени, и для того, чтобы создать карту, которая содержит каждый набор символов, для которого поддержка доступна в текущей виртуальной машине Java. Поддержка новых наборов символов может быть добавлена через интерфейс поставщика услуг, определенный в CharsetProvider класс. Все методы, определенные в этом классе, безопасны для использования многократными параллельными потоками.
Имена набора символов
- Прописные буквы ‘A’ через ‘Z’ (‘u0041’ через ‘u005a’),
- Строчные буквы ‘a’ через ‘z’ (‘u0061’ через ‘u007a’),
- Цифры ‘0’ через ‘9’ (‘u0030’ через ‘u0039’),
- Символ тире ‘-‘ (‘u002d’, ДЕФИС — МИНУС
- Плюс символьный ‘+’ (‘u002b’, ЗНАК «ПЛЮС»
- Символ точки ‘.’ (‘u002e’, ТОЧКА
- Символ двоеточия ‘:’ (‘u003a’, ДВОЕТОЧИЕ
- Символ подчеркивания ‘_’ (‘u005f’, НИЗКАЯ СТРОКА
Стандартные наборы символов
Набор символов Описание US-ASCII Семиразрядный ASCII, a.k.a. ISO646-US, a.k.a. Основной латинский блок набора символов Unicode ISO-8859-1 Латинский Алфавит № 1 ISO, a.k.a. ISO-LATIN-1 UTF-8 Восьмиразрядный Формат Преобразования UCS UTF-16BE Шестнадцатиразрядный Формат Преобразования UCS, обратный порядок байтов UTF-16LE Шестнадцатиразрядный Формат Преобразования UCS, прямой порядок байтов UTF-16 Шестнадцатиразрядный Формат Преобразования UCS, порядок байтов идентифицируется дополнительной меткой порядка байтов
- Декодируя, UTF-16BE и наборы символов UTF-16LE интерпретируют начальные метки порядка байтов как НЕРАЗРЫВНЫЙ ПРОБЕЛ НУЛЕВОЙ ШИРИНЫ
- Декодируя, набор символов UTF-16 интерпретирует метку порядка байтов в начале входного потока, чтобы указать на порядок байтов потока, но значений по умолчанию к обратному порядку байтов, если нет никакой метки порядка байтов; кодируя, это использует обратный порядок байтов и пишет метку порядка байтов с обратным порядком байтов.
У каждого экземпляра виртуальной машины Java есть набор символов по умолчанию, который может или, возможно, не является одним из стандартных наборов символов. Набор символов по умолчанию определяется во время запуска виртуальной машины и обычно зависит от локали и набора символов, используемого базовой операционной системой.
Java для начинающих. Урок 7. Символьный тип данных Char
Java — урок 6.3 (Работа с масcивами сивловов таблицы ASCII)
StandardCharsets класс определяет константы для каждого из стандартных наборов символов.
Терминология
Имя этого класса берется из терминов, использованных в RFC 2278 . В том документе набор символов определяется как комбинация одного или более кодированных наборов символов и схемы кодировки символов. (Это определение сбивает с толку; некоторые другие системы программного обеспечения определяют набор символов как синоним для кодированного набора символов.)
Кодированный набор символов является отображением между рядом абстрактных символов и рядом целых чисел. US-ASCII, ISO 8859-1, JIS X 0201, и Unicode являются примерами кодированных наборов символов.
Некоторые стандарты определили набор символов, чтобы быть просто рядом абстрактных символов без связанной присвоенной нумерации. Алфавит является примером такого набора символов. Однако, тонкое различие между набором символов и кодированным набором символов редко используется практически; прежний стал краткой формой для последнего, включая в спецификации API Java.
Схема кодировки символов является отображением между одним или более кодированными наборами символов и рядом октета (восьмиразрядный байт) последовательности. UTF-8, UTF-16, ISO 2022, и EUC являются примерами схем кодировки символов. Схемы кодирования часто связываются с определенным кодированным набором символов; UTF-8, например, используется только, чтобы закодировать Unicode. Некоторые схемы, однако, связываются с многократными кодированными наборами символов; EUC, например, может использоваться, чтобы закодировать символы во множестве азиатских кодированных наборов символов.
Когда кодированный набор символов используется исключительно с единственной схемой кодировки символов тогда, соответствующий набор символов обычно назван по имени кодированного набора символов; иначе набор символов обычно назван по имени схемы кодирования и, возможно, локаль кодированных наборов символов, которые это поддерживает. Следовательно US-ASCII является и именем кодированного набора символов и набора символов, который кодирует это, в то время как EUC-JP является именем набора символов, который кодирует JIS X 0201, JIS X 0208, и JIS X 0212 кодированных наборов символов для японского языка.
Собственная кодировка символов языка программирования Java является UTF-16. Набор символов в платформе Java поэтому определяет отображение между последовательностями шестнадцатиразрядных элементов кода UTF-16 (то есть, последовательностями случайных работ) и последовательностями байтов.
Сводка конструктора
protected | Charset(String canonicalName, String[] aliases) |
Инициализирует новый набор символов с данным каноническим именем и набором псевдонима.
Сводка метода
Set | aliases() |
Источник: spec-zone.ru
Ошибка в вопросе «Java программирование 1.5»
Вопрос:
Необходимо определить в программе символ с кодом 514.
Какой из приведенных фрагментов кода позволит решить оставленную задачу?
1) char c =’u514′;
2) char c =’222′;
3) char c =’u222′;
4) char c =’514′;
5) char c =’u0222′;
Комментарий:
Ну, так вот ни одного правильного ответа.
есть два способа задать символ с кодом 514;
char c=514;//без кавычек
char c=’u0202′;
‘u0222’=512+32+2=546.
Что думают составители?
# Леонид Евстигнеев 2009-05-11 09:59
Пара опечаток.
В вопросе:
Каким будет результат выполнения приведенного фрагмента кода?
Дано два одинаковых ответа:
x=2
x=1
В вопросе:
Какую из строк необходимо добавить на место пропущенной в приведенном фрагменте кода, чтобы результатом его выполнения стала строка «Hello»?
Есть строка
String strs = new String[] ;
А должна быть
String[] strs = new String[] ;
И ещё везде страдает форматирование кода.
# Алексей Кураков 2009-05-11 10:09
Вы, правы, конечно же, 0202, а не 0222, уже поправили. Два, других, в процессе.
# Леонид Евстигнеев 2009-05-11 10:13
Вопрос:
Какой из перечисленных методов допускает его перекрытие(overriding) в подклассах?
1) public abstract void method m1()
2) public static void method m1()
3) public final void method m1()
4) public static final void method m1()
5) public void method m1()
Первое, модификатора method в Java нет.
Судя по всему опять опечатка и везде должно быть написано method_m1.
Второе, может я сильно заблуждаюсь, но имплементирование абстрактного метода это частный случай перекрытия(переопределения). Тогда тут два правильных ответа, а возможен выбор только одного.
# Леонид Евстигнеев 2009-05-11 10:23
Вопрос:
Необходимо определить, ссылаются ли объекты File f1 и File f2 на один и тот же файл на диске. Какой из приведённых фрагментов кода позволит решить поставленную задачу?
(Выбор одного варианта)
1) f1.getCanonicalPath().equals(f2.getCanonicalPath())
2) f1.compareTo(f2)==0
3) f1.getPath().equals(f2.getPath())
4) f1.equals(f2)
5) f1.getName().equals(f2.getName())
Комментарий:
Ответы 1,2,4 приведут вас к одинаковому результату.
f1.equals(. ) вообще реализован через с помощью f1.compareTo()
Надо как-то переформулировать вопрос.
# Леонид Евстигнеев 2009-05-11 10:40
Вопрос:
Необходимо определить номер текущего дня недели.
Какой из приведенных фрагментов кода позволит решить поставленную задачу?
(Выбор одного варианта)
1)int day = new Date().getDay();
2)Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
int day = calendar.get(Calendar.DAY_OF_WEEK);
3).
4).
5).
1 и 2 решают вопрос. Хотя первый вариант и объявлен deprecated. И номера дня совсем разные. Может лучше заменить вариант 1 на совсем неправильный?
# Алексей Кураков 2009-05-14 09:35
Леонид, в ближайшее время, проверим все перечисленные вопросы.
# Леонид Евстигнеев 2009-05-17 00:19
Должен отметить, что тест очень хороший.
Если вы не против, я буду продолжать писать свои замечания здесь.
ВОПРОС:
Необходимо получить ClassLoader, который используется для текущего потока. Какой из приведённых фрагментов кода позволит решить поставленную задачу?
1) ClassLoader cl = Runtime.getCurrentClassLoader();
2) ClassLoader cl = Process.getClassLoader();
3) ClassLoader cl = Thread.getContextClassLoader();
4) ClassLoader cl = System.getClassLoader();
5) ClassLoader cl = System.getSecurityManaer().currentClassLoader()
КОММЕНТАРИЙ:
Правильный ответ никакой.
Хотя подразумевался ответ под номером 3. Но с ним проблема в том, что он не будет компилировать ни под каким предлогом. Да, у Thread есть метод getContextClassLoader, но это не метод класса и вызывать его так как написано нельзя. Вызывать этот метод можно только у объекта. Правильный вариант может выглядеть так:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
# Леонид Евстигнеев 2009-05-26 01:09
ВОПРОС:
Даны следующие описания интерфейсов:
interface I1 void m1() throws IOException;
>
interface I2 void m1() throws SQLException;
>
Какой из перечисленных методов должен быть реализован классом, реализующим в, свою очередь интерфейсы I1 и I2 одновременно?
(Выбор одного варианта)
1)public void m1() throws SQLException, IOException;
2)Класс public void m1() throws IOException; в случае успешной реализации public void m1() throws SQLException;
3)Класс public void m1() throws SQLException; в случае успешной реализации public void m1() throws IOException;
4)Оба, public void m1() throws SQLException; и public void m1() throws IOException;
5)public void m1() throws Exception
КОММЕНТАРИЙ:
Опять нет правильного ответа.
во 2 и 3 варианте вообще непонятно, что имеется ввиду.
4 неправильный т.к. в одном классе не может быть двух методов с одинаковой сигнатурой.
5 неправилен т.к. тип возбуждаемого исключения методом m1 более общий чем указан в интерфейсах.
1 вариант неправилен т.к. интерфес I1 не возбуждает исключение SQLException, а интерфес I2 не возбуждает исключение IOException.
При поставленных условиях нельзя реализовать интерфейсы I1 и I2 одновременно т.к. возбуждаемые в их методах m1() исключения несовместимы они из разных ветвей иерархии. Имплементируемый метод m1 из интерфеса может возбуждать исключения либо того же типа, что указан в интерфейсе, либо типа наследника исключения указанного в интерфейсе.
То есть, реализовать метод m1 сразу двух интерфейсов можно только если эти методы возбуждают совместимые исключения. Или другими словами тип одного исключения должен быть потомком типа другого исключения.
# Леонид Евстигнеев 2009-08-21 11:12
И снова здравствуйте.
Опять проходил тест по Java.
В результатах сдачи написано: Потоки 3/4.
Хотелось бы узнать в каком вопросе ошибка?
Вот эти четыре вопроса, которые мне попались.
1)
Какой метод класса Thread используется для зауска нового потока выполнения?
Ответ: start();
2)
Каким будет результат риведенного фрагмента кода?
public class ThreadTest extends Thread public void run() System.out.println(«In run»);
yield();
System.out.println(«Leaving run»);
>
public static void main(String[] args) (new ThreadTest()).start();
>
>
Ответ:
In run
Leaving run
Даже если проверить в рабочей среде так и будет.
3)
Каким будет результат риведенного фрагмента кода?
public class Test extends Thread public void run() System.out.println(«1»);
yield();
System.out.println(«2»);
suspend();
System.out.println(«3»);
resume();
System.out.println(«4»);
>
public static void main(String[] args) Test t = new Test();
t.start();
>
>
Ответ: 12
suspend и resume — deprecated. А Проверка этого кода даёт указанный ответ.
4)
Какое из утверждений относительно приведенного фрагмента кода является верным?
class Test implements Runnable public static void main(String[] args) Thread t = new Thread (new Test());
t.start();
>
public void run(int limit) for (int x = 0; x Предыдущая 1 2 Следующая
Источник: certifications.ru
Java: Русские буквы и не только.
Некоторые проблемы настолько сложны,
что нужно быть очень умным и очень хорошо
информированным, чтобы не быть уверенным
в их решении.
Лоренс Дж. Питер
Peter’s Almanac
Кодировки
Когда я только начинал программировать на языке C, первой моей программой (не считая HelloWorld) была программа перекодировки текстовых файлов из основной кодировки ГОСТ-а (помните такую? 🙂 в альтернативную. Было это в далёком 1991-ом году. С тех пор многое изменилось, но за прошедшие 10 лет подобные программки свою актуальность, к сожалению, не потеряли. Слишком много уже накоплено данных в разнообразных кодировках и слишком много используется программ, которые умеют работать только с одной. Для русского языка существует не менее десятка различных кодировок, что делает проблему ещё более запутанной.
Откуда же взялись все эти кодировки и для чего они нужны? Компьютеры по своей природе могут работать только с числами. Для того чтобы хранить буквы в памяти компьютера надо поставить в соответствие каждой букве некое число (примерно такой же принцип использовался и до появления компьютеров — вспомните про ту же азбуку Морзе).
Причём число желательно поменьше — чем меньше двоичных разрядов будет задействовано, тем эффективнее можно будет использовать память. Вот это соответствие набора символов и чисел собственно и есть кодировка. Желание любой ценой сэкономить память, а так же разобщённость разных групп компьютерщиков и привела к нынешнему положению дел.
Самым распространённым способом кодирования сейчас является использование для одного символа одного байта (8 бит), что определяет общее кол-во символов в 256. Набор первых 128 символов стандартизован (набор ASCII) и является одинаковыми во всех распространённых кодировках (те кодировки, где это не так уже практически вышли из употребления). Англицкие буковки и символы пунктуации находятся в этом диапазоне, что и определяет их поразительную живучесть в компьютерных системах :-). Другие языки находятся не в столь счастливом положении — им всем приходится ютиться в оставшихся 128 числах.
Unicode
В конце 80-х многие осознали необходимость создания единого стандарта на кодирование символов, что и привело к появлению Unicode. Unicode — это попытка раз и навсегда зафиксировать конкретное число за конкретным символом. Понятно, что в 256 символов тут не уложишься при всём желании. Довольно долгое время казалось, что уж 2-х то байт (65536 символов) должно хватить.
Ан нет — последняя версия стандарта Unicode — 3.1 определяет уже 94140 символов. Для такого количества символов, наверное, уже придётся использовать 4 байта (4294967296 символов). Может быть и хватит на некоторое время. 🙂
В набор символов Unicode входят всевозможные буквы со всякими чёрточками и припендюльками, греческие, математические, иероглифы, символы псевдографики и пр. и пр. В том числе и так любимые нами символы кириллицы (диапазон значений 0x0400-0x04ff). Так что с этой стороны никакой дискриминации нет.
Если Вам интересны конкретные кода символов, для их просмотра удобно использовать программу «Таблица символов» из WinNT. Вот, например, диапазон кириллицы:
Если у Вас другая OS или Вас интересует официальное толкование, то полную раскладку символов (charts) можно найти на официальном сайте Unicode.
Типы char и byte
В Java для символов выделен отдельный тип данных char размером в 2 байта. Это часто порождает путаницу в умах начинающих (особенно если они раньше программировали на других языках, например на C/C++). Дело в том, что в большинстве других языков для обработки символов используются типы данных размером в 1 байт.
Например, в C/C++ тип char в большинстве случаев используется как для обработки символов, так и для обработки байтов — там нет разделения. В Java для байтов имеется свой тип — тип byte. Таким образом C-ишному char соответствует Java-вский byte, а Java-вскому char из мира C ближе всего тип wchar_t. Надо чётко разделять понятия символов и байтов — иначе непонимание и проблемы гарантированны.
Java практически с самого своего рождения использует для кодирования символов стандарт Unicode. Библиотечные функции Java ожидают увидеть в переменных типа char символы, представленные кодами Unicode.
В принципе, Вы, конечно, можете запихнуть туда что угодно — цифры есть цифры, процессор всё стерпит, но при любой обработке библиотечные функции будут действовать исходя из предположения что им передали кодировку Unicode. Так что можно спокойно полагать, что у типа char кодировка зафиксирована. Но это внутри JVM.
Когда данные читаются извне или передаются наружу, то они могут быть представлены только одним типом — типом byte. Все прочие типы конструируются из байтов в зависимости от используемого формата данных. Вот тут то на сцену и выходят кодировки — в Java это просто формат данных для передачи символов, который используется для формирования данных типа char.
Для каждой кодовой страницы в библиотеке имеется по 2 класса перекодировки (ByteToChar и CharToByte). Классы эти лежат в пакете sun.io. Если, при перекодировке из char в byte не было найдено соответствующего символа, он заменяется на символ «?».
Кстати, эти файлы кодовых страниц в некоторых ранних версиях JDK 1.1 содержат ошибки, вызывающие ошибки перекодировок, а то и вообще исключения при выполнении. Например, это касается кодировки KOI8_R. Лучшее, что можно при этом сделать — сменить версию на более позднюю. Судя по Sun-овскому описанию, большинство этих проблем было решено в версии JDK 1.1.6.
До появления версии JDK 1.4 набор доступных кодировок определялся только производителем JDK. Начиная с 1.4 появилось новое API (пакет java.nio.charset), при помощи которого Вы уже можете создать свою собственную кодировку (например поддержать редко используемую, но жутко необходимую именно Вам).
Класс String
В большинстве случаев для представления строк в Java используется объект типа java.lang.String. Это обычный класс, который внутри себя хранит массив символов (char[]), и который содержит много полезных методов для манипуляции символами. Самые интересные — это конструкторы, имеющие первым параметром массив байтов (byte[]) и методы getBytes(). При помощи этих методов Вы можете выполнять преобразования из массива байтов в строки и обратно. Для того, чтобы указать какую кодировку при этом использовать у этих методов есть строковый параметр, который задаёт её имя. Вот, например, как можно выполнить перекодировку байтов из КОИ-8 в Windows-1251:
//Данные в кодировке КОИ-8 byte[] koi8Data=. ; //Преобразуем из КОИ-8 в Unicode String string=new String(koi8Data,»KOI8_R»); //Преобразуем из Unicode в Windows-1251 byte[] winData=string.getBytes(«Cp1251»);
Список 8-ми битовых кодировок, доступных в современных JDK и поддерживающих русские буквы Вы можете найти ниже, в разделе «8-ми битовые кодировки русских букв».
Так как кодировка — это формат данных для символов, кроме знакомых 8-ми битовых кодировок в Java также на равных присутствуют и многобайтовые кодировки. К таким относятся UTF-8, UTF-16, Unicode и пр. Например вот так можно получить байты в формате UnicodeLittleUnmarked (16-ти битовое кодирование Unicode, младший байт первый, без признака порядка байтов):
//Строка Unicode String string=». «; //Преобразуем из Unicode в UnicodeLittleUnmarked byte[] data=string.getBytes(«UnicodeLittleUnmarked»);
При подобных преобразованиях легко ошибиться — если кодировка байтовых данных не соответствуют указанному параметру при преобразовании из byte в char, то перекодирование будет выполнено неправильно. Иногда после этого можно вытащить правильные символы, но чаще всего часть данных будет безвозвратно потеряна.
В реальной программе явно указывать кодовую страницу не всегда удобно (хотя более надёжно). Для этого была введена кодировка по умолчанию. По умолчанию она зависит от системы и её настроек (для русских виндов принята кодировка Cp1251), и в старых JDK её можно изменить установкой системного свойства file.encoding. В JDK 1.3 изменение этой настройки иногда срабатывает, иногда — нет.
Вызвано это следующим: первоначально file.encoding ставится по региональным настройкам компьютера. Ссылка на кодировку по умолчанию запоминается в нутрях при первом преобразовании. При этом используется file.encoding, но это преобразование происходит ещё до использования аргументов запуска JVM (собсно, при их разборе).
Вообще-то, как утверждают в Sun, это свойство отражает системную кодировку, и она не должна изменяться в командной строке (см., например, комментарии к BugID 4163515). Тем не менее в JDK 1.4 Beta 2 смена этой настройки опять начала оказывать эффект. Что это, сознательное изменение или побочный эффект, который может опять исчезнуть — Sun-овцы ясного ответа пока не дали.
Эта кодировка используется тогда, когда явно не указанно название страницы. Об этом надо всегда помнить — Java не будет пытаться предсказать кодировку байтов, которые Вы передаёте для создания строки String (так же она не сможет прочитать Ваши мысли по этому поводу :-). Она просто использует текущую кодировку по умолчанию. Т.к. эта настройка одна на все преобразования, иногда можно наткнуться на неприятности.
Для преобразования из байтов в символы и обратно следует пользоваться только этими методами. Простое приведение типа использовать в большинстве случаев нельзя — кодировка символов при этом не будет учитываться. Например, одной из самых распространённых ошибок является чтение данных побайтно при помощи метода read() из InputStream, а затем приведение полученного значения к типу char:
InputStream is=. ; int b; StringBuffer sb=new StringBuffer(); while((b=is.read())!=-1) < sb.append((char)b); // так делать нельзя >String s=sb.toString();
Обратите внимание на приведение типа — «(char)b». Значения байтов вместо перекодирования просто скопируются в char (диапазон значений 0-0xFF, а не тот, где находится кириллица).
Такому копированию соответствует кодировка ISO-8859-1 (которая один в один соответствует первым 256 значениям Unicode), а значит, можно считать, что этот код просто использует её (вместо той, в которой реально закодированы символы в оригинальных данных). Если Вы попытаетесь отобразить полученное значение — на экране будут или вопросики или кракозяблы. Например, при чтении строки «АБВ» в виндовой кодировке может запросто отобразиться что-то вроде такого: «»ÀÁ». Подобного рода код часто пишут программисты на западе — с английскими буквами работает, и ладно. Исправить такой код легко — надо просто заменить StringBuffer на ByteArrayOutputStream:
InputStream is=. ; int b; ByteArrayOutputStream baos=new ByteArrayOutputStream(); while((b=is.read())!=-1) < baos.write(b); >//Перекодирование байтов в строку с использованием //кодировки по умолчанию String s=baos.toString(); //Если нужна конкретная кодировка — просто укажите //её при вызове toString(): // //s=baos.toString(«Cp1251»);
Более подробно о распространённых ошибках смотрите раздел «Типичные ошибки».
Источник: alterstudy.ru