Я полагаю, что есть два связанных использования канонического: формы и экземпляры.
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
является типом enum. Делать это для своих собственных занятий, безусловно, возможно, но это необходимо. Прочитайте Effective Java Джоша Блоха для подробностей и советов.