2008-11-11 115 views

回答

46

維基百科指向術語Canonicalization

將具有多個可能表示的數據轉換爲「標準」規範表示的過程。這可以通過比較不同表示的等價性,計算不同數據結構的數量,通過消除重複計算來提高各種算法的效率,或者使強加一個有意義的排序順序成爲可能。

的Unicode例子作出的最有意義的我:

Unicode標準的可變長度編碼,特別是UTF-8,具有用於最常用的字符多於一個的可能的編碼。這使得字符串驗證更加複雜,因爲必須考慮每個字符串字符的每種可能的編碼。一個不考慮所有字符編碼的軟件實現會冒着接受在應用程序設計中認爲無效的字符串的風險,這可能會導致錯誤或允許攻擊。解決方案是爲每個字符提供單個編碼。規範化是將每個字符串字符轉換爲單個允許的編碼的過程。另一種方法是讓軟件確定一個字符串是否是規範化的,如果不是則拒絕。在這種情況下,在客戶端/服務器環境中,規範化將是客戶端的責任。

總之,一個標準的數據表示形式。從這個表格中,您可以轉換爲您可能需要的任何表示。

21

「canonical」一詞只是「標準」或「通常」的同義詞。它沒有任何Java特定的含義。

+3

規範具有比標準或常用IMO更豐富的含義的天然唯一表示。 – 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 

該文件的標準表示的經典定義將是最後一條路徑。使用本地或相對路徑,無法在沒有上下文信息的情況下全局識別資源。使用絕對路徑可以識別資源,但不能分辨兩個路徑是否引用同一個實體。將兩條或多條路徑轉換爲規範形式時,可以執行上述所有操作,並確定兩個資源是否相同,如果這對您的應用程序很重要(解決別名問題)。

請注意,資源的規範形式不是該特定形式本身的質量;對於給定類型(比如文件路徑),可能會有多種可能的規範形式(比如,按字典順序排列,首先是所有可能的絕對路徑)。一種形式只是被選爲特定應用原因的規範形式,或者可能是任意的,以至於每個人都會說同一種語言。

強制對象到其規範的情況下是相同的基本理念,但不是確定資源的一個「最佳」的代表,它任意選擇一類具有相同的「內容」情況下的一個實例爲規範引用,然後將所有引用轉換爲等效對象以使用一個規範實例。

這可以用作優化時間和空間的技術。如果應用程序中存在多個等效對象的實例,那麼通過強制它們全部被解析爲特定值的單個規範實例,您可以消除每個值之外的所有值,從而節省空間和可能的時間,因爲您現在可以比較那些具有參考標識(==)的值而不是對象等值(equals()方法)。

使用規範實例優化性能的經典示例是摺疊具有相同內容的字符串。在具有相同字符序列的兩個字符串上調用String.intern()將保證爲該文本返回相同的規範字符串對象。如果您將所有字符串傳遞給該規範化器,則知道等價字符串實際上是相同的對象引用,即別名

Java 5.0+中的枚舉類型強制特定枚舉值的所有實例在一個枚舉值中使用相同的規範實例虛擬機,即使該值是序列化和反序列化。這就是爲什麼如果Days是一個枚舉類型,你可以在java中使用if (day == Days.SUNDAY)而不受懲罰。爲你自己的班級做這件事當然是可能的,但要小心。閱讀有效的Java Josh Bloch瞭解詳情和建議。

14

減少到最簡單,最顯著的形式不失一般性

0

規範的表示意味着查看字符在不同的風格 例如,如果我寫了一個字母A指其他人可以寫字母A在不同的風格:)

這是根據光學字符識別技術領域

2

另一個很好的例子可能是:您有支持使用笛卡爾(X,Y,Z)的一類,球形(R,θ,Φ)和圓柱座標(r,phi,z)。爲了建立平等(等於方法),您可能希望將所有表示轉換爲您選擇的一個「規範」表示,例如,球面座標。 (或者你可能希望這樣做 - 即使用一個內部表示。)我不是專家,但這對我來說確實是一個很好的具體例子。

4

一個簡單的方法來記住它是在神學界使用「規範」的方式,規範的真理是真實的事實,所以如果兩個人發現它,他們已經找到了相同的真相。與規範實例相同。如果您認爲您找到了其中兩個(即a.equals(b)),那麼您確實只有一個(即a == b)。所以平等意味着規範對象的身份。

現在進行比較。您現在可以選擇使用a==ba.equals(b),因爲它們在規範實例的情況下會產生相同的答案,但是a == b是參考的比較(JVM可以非常快速地比較兩個數字,因爲它們只是兩個。相比a.equals(b)這是一個方法調用和涉及多個開銷32位模式

21

一個很好的例子爲理解「規範形式/再現」是看的「布爾」 XML模式數據類型定義:

  • 布爾的「詞彙表示」可以是以下之一:{true, false, 1, 0}
  • 「規範表示」只能是{true, false}

這一次,在本質上,這意味着

  • "true""1"被映射到規範的再版。 "true"
  • "false""0"被映射到規範repr。 "false"

看到the w3 XML schema datatype definition for boolean

0

規範形式意味着元素