Что означает термин "каноническая форма" или "каноническое представление" в Java?

Я часто слышал, что этот термин используется, но я никогда не понимал его.

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

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

Ответ 1

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

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

Пример Юникод дал мне больше всего смысла:

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

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

Ответ 2

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

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

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

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

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

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

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

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

Ответ 3

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

Ответ 4

Хорошим примером для понимания "канонической формы/представления" является рассмотрение определения типа данных XML-схемы "boolean":

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

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

  • "true" и "1" отображаются в каноническое представление. "true" и
  • "false" и "0" сопоставляются с канонциальным выражением. "false"

см. определение типа данных схемы XML w3 для булевых

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

Ответ 8

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

Это в соответствии с ПОЗИЦИОНИРОВАНИЕМ ОПТИЧЕСКОГО ХАРАКТЕРА

Ответ 9

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