2008-11-11 2 views
67

Я часто слышал, что этот термин используется, но я его никогда не понимал.Что означает термин «каноническая форма» или «каноническое представление» в Java?

Что это значит, и может ли кто-нибудь привести некоторые примеры/указать мне ссылки?

EDIT: Спасибо всем за ответы. Можете ли вы также рассказать мне, как каноническое представление полезно в производительности equals(), как указано в Effective Java?

ответ

46

Википедия указывает на термин Canonicalization.

Процесс преобразования данных, имеющих более одного возможного представления в «стандартное» каноническое представление. Это можно сделать, чтобы сравнить различные представления для эквивалентности, подсчитать количество различных структур данных, повысить эффективность различных алгоритмов, устранив повторные вычисления или сделать возможным навязать осмысленный порядок сортировки.

Unicode пример сделал больше смысла для меня:

переменной длины кодировки в стандарте Unicode, в частности, UTF-8, имеют более одного возможного кодирования для наиболее распространенных символов. Это делает проверку строки более сложной, поскольку необходимо учитывать все возможные кодировки каждого символа строки. Программная реализация, которая не учитывает все кодировки символов, рискует принять строки, которые считаются недействительными в дизайне приложения, что может вызвать ошибки или разрешить атаки. Решение состоит в том, чтобы разрешить одиночную кодировку для каждого символа. Канонизация - это процесс перевода каждого символа строки на его единственную разрешенную кодировку. Альтернативой является программное обеспечение для определения того, какова ли строка канонизирована, а затем отклонить ее, если она не является. В этом случае, в контексте клиент/сервер, канонизацизация будет зависеть от клиента.

Таким образом, стандартная форма представления данных. Из этой формы вы можете конвертировать в любое представление, которое вам может понадобиться.

21

Слово «канонический» является просто синонимом «стандартного» или «обычного». Он не имеет никакого специфического для Java значения.

+3

канонических имеет более богатый смысл, чем стандартные или обычный ИМО. – squid 2015-11-12 15:20:47

53

Я считаю, что существуют два родственных применения канонических: форм и экземпляров.

A каноническая форма означает, что значения определенного типа ресурса могут быть описаны или представлены несколькими способами, и один из этих способов выбран в качестве предпочтительной канонической формы. (Эта форма канонизирована, как книги, которые превратили ее в библию, а другие формы - нет.) Классическим примером канонической формы являются пути в иерархической файловой системе, где один файл может ссылаться на число способов:

myFile.txt         # in current working dir 
../conf/myFile.txt       # relative to the CWD 
/apps/tomcat/conf/myFile.txt     # absolute path using symbolic links 
/u1/local/apps/tomcat-5.5.1/conf/myFile.txt # absolute path with no symlinks 

Классическое определение канонического представления этого файла будет последним путем. С локальными или относительными путями вы не можете глобально идентифицировать ресурс без контекстной информации. С абсолютными путями вы можете идентифицировать ресурс, но не можете определить, относятся ли два пути к одному и тому же объекту. Если два или более пути преобразуются в их канонические формы, вы можете сделать все вышеизложенное, а также определить, являются ли два ресурса одинаковыми или нет, если это важно для вашего приложения (решение проблема сглаживания).

Обратите внимание, что каноническая форма ресурса не является качеством самой конкретной формы; может быть несколько возможных канонических форм для заданного типа, например, путей к файлам (скажем, лексикографически, в первую очередь возможных абсолютных путей). Одна форма просто выбирается как каноническая форма для конкретной причины применения или может быть произвольно, чтобы все говорили на одном языке.

Принуждение объектов в их канонических экземпляров это та же самая основная идея, но вместо того, чтобы определить один «лучшее» представление ресурса, он произвольно выбирает один экземпляр класса экземпляров с тем же «содержанием», как канонические reference, затем преобразует все ссылки на эквивалентные объекты для использования одного канонического экземпляра.

Это может использоваться как метод оптимизации времени и пространства. Если в приложении есть несколько экземпляров эквивалентных объектов, то, заставляя их все решать как единственный канонический экземпляр определенного значения, вы можете исключить все, кроме одного, значения, экономя пространство и, возможно, время, так как теперь вы можете сравнить эти значения с эталонным идентификатором (==) в отличие от эквивалентности объектов (метод equals()).

Классический пример оптимизации производительности с каноническими экземплярами - это свертывание строк с одним и тем же контентом. Вызов String.intern() на две строки с одинаковой последовательностью символов гарантированно возвращает тот же канонический объект String для этого текста. Если вы передаете все свои строки через этот канонизатор, вы знаете, что эквивалентные строки на самом деле идентичные ссылки на объекты, то есть псевдонимы

Типы перечислений в Java 5.0+ заставляют все экземпляры определенного значения перечисления использовать один и тот же канонический экземпляр внутри VM, даже если значение сериализовано и десериализовано. Вот почему вы можете использовать if (day == Days.SUNDAY) с безнаказанностью в java, если Days - тип перечисления. Выполнение этого для ваших собственных занятий, безусловно, возможно, но заботится. Прочитайте Эффективная Java от Джоша Блоха за подробностями и советами.

14

сводится к простейшей и наиболее значимой форме без потери общности

0

канонического представления означает, просматривать характер в другом стиле , например, если я пишу письмо А значит, другой человек может написать письмо А в другом стиле :)

Это в соответствии с оптических распознаванием символов ПОЛЕ

2

Другим хорошим примером может быть: у вас есть класс, который поддерживает использование декартова (х, у, г), сферические (г, тета, фи) и цилиндрический координаты (r, phi, z). В целях установления равенства (метод равенства) вы, вероятно, захотите преобразовать все представления в одно «каноническое» представление по вашему выбору, например. сферические координаты. (Или, может быть, вы хотели бы сделать это в целом - например, использовать одно внутреннее представление.) Я не эксперт, но это произошло со мной, как с хорошим конкретным примером.

4

Простой способ запомнить это способ «канонический» используется в богословских кругах, каноническая истина - настоящая истина, поэтому, если два человека найдут это, они нашли ту же самую истину. То же самое с каноническим экземпляром. Если вы считаете, что нашли два из них (т. Е. a.equals(b)), у вас действительно есть только один (то есть a == b). Таким образом, равенство означает тождество в случае канонического объекта.

Теперь для сравнения.Теперь у вас есть выбор использования a==bилиa.equals(b), так как они будут выдавать один и тот же ответ в случае канонического экземпляра, но a == b - сравнение ссылки (JVM может сравнивать два числа чрезвычайно быстро, поскольку они всего лишь два . 32 разрядные модели по сравнению с a.equals(b), который является методом вызова и включает в себя больше накладных расходов

21

хороший пример для понимания «канонической формы/представления», чтобы посмотреть на XML-схемы определения типа данных «булево»:

  • «лексическое представление» булева может быть одним из: {true, false, 1, 0}, тогда как
  • «каноническое представление» может быть только один из {true, false}

Это, в сущности, означает, что

  • "true" и "1" получить карту к каноническому предст. "true" и
  • "false" и "0" получить сопоставление с канонической категорией. "false"

см the w3 XML schema datatype definition for boolean

0

Каноническая форма означает естественно уникальное представление элемента

Смежные вопросы