我经常听到这个术语被使用,但我从来没有真正理解它.
这是什么意思,任何人都可以举一些例子/指点我的链接?
编辑:感谢大家的回复.你能告诉我规范表示在equals()性能中是如何有用的,如Effective Java中所述?
我相信规范有两个相关用途:表单和实例.
甲规范形式表示特定类型的资源的值可以描述或以多种方式来表示,并且这些方式中的一种被选择作为有利规范形式.(这种形式是封装的,就像书籍成为圣经,而其他形式则不是.)规范形式的典型例子是分层文件系统中的路径,其中可以通过多种方式引用单个文件:
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+中的枚举类型强制特定枚举值的所有实例在VM中使用相同的规范实例,即使该值已序列化和反序列化也是如此.这就是为什么你可以使用if (day == Days.SUNDAY)
java中的有罪不罚,如果Days
是枚举类型.为你自己的课程做这个当然是可能的,但要小心.阅读Josh Bloch撰写的Effective Java,了解详细信息和建议.
维基百科指的是Canonicalization一词.
将具有多个可能表示的数据转换为"标准"规范表示的过程.可以这样做以比较不同的等价表示,计算不同数据结构的数量,通过消除重复计算来提高各种算法的效率,或者使得可以施加有意义的排序顺序.
在Unicode的例子才是最有意义的对我说:
Unicode标准中的可变长度编码,特别是UTF-8,对于大多数常见字符具有多种可能的编码.这使得字符串验证更加复杂,因为必须考虑每个字符串字符的每个可能的编码.不考虑所有字符编码的软件实现存在接受在应用程序设计中被视为无效的字符串的风险,这可能导致错误或允许攻击.解决方案是允许每个字符进行单一编码.然后,规范化是将每个字符串字符转换为其允许的单个编码的过程.另一种方法是软件确定字符串是否规范化,如果不是则拒绝它.在这种情况下,在客户端/服务器上下文中,规范化将是客户端的责任.
总之,数据的标准表示形式.然后,您可以从此表单转换为您可能需要的任何表示形式.
理解"规范形式/表示"的一个很好的例子是查看"boolean"的XML模式数据类型定义:
布尔值的"词法表示"可以是以下之一:{true, false, 1, 0}
而
"规范表征"只能是其中之一 {true, false}
从本质上讲,这意味着
"true"
并"1"
映射到规范的repr."true"
和
"false"
并被"0"
映射到canoncial repr."false"
请参阅boolean的w3 XML模式数据类型定义
"规范"一词只是"标准"或"通常"的同义词.它没有任何特定于Java的含义.
在不失一般性的情况下,简化为最简单,最重要的形式