Я считаю, что есть два связанных использования слова canonical: формы и экземпляры.
А каноническая форма , означает , что значения определенного типа ресурса могут быть описаны или представлены несколько способами, и один из этих способов выбираются в качестве благоприятствования канонической формы. (Эта форма канонизирована , как книги, вошедшие в библию, а другие формы - нет.) Классическим примером канонической формы являются пути в иерархической файловой системе, где на один файл можно ссылаться несколькими способами. :
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 » Джоша Блоха для получения подробной информации и советов.