Java对类,方法,字段和变量名具有强大的命名约定。 例如:
JDK对这两条规则的例外情况很少。
但是一个约定不是一个语法规则,因此下面的类没有错误编译(C#程序员会很开心):
public class string {
private char[] C;
public int Length() { return C.length; }
}
但是,约定和语法规则之间的差距是不可避免的,这会导致初学者违反惯例,从而导致对命名约定的冗长解释。
如果最基本的命名约定(如上所述)将成为语法的一部分,那么Java编译器会强制执行它们并自动教育那些初学者。
所以这就是问题:
从Java语言设计者的角度来看:有没有什么理由在语法和命名约定之间留下一个不应该被违反的空白?是否有任何有意义的用例(类,方法,字段,变量)违反惯例但超出惯例有意义?
答案 0 :(得分:3)
在定义语言之后很久就编写了这些约定,因此可以在不破坏兼容性的情况下对其进行改进。惯例的问题是涉及品味。例如空格或制表符,使用$
作为变量名称,使用m_
或_
等开始字段名称,甚至将get
和set
添加到getter和塞特犬(我不喜欢)
Java实际上允许你做一些让C程序员感到不安的事情。为什么他们允许这个我不知道,但我认为他们不想通过施加比实际需要更多的规则来限制采用。
请注意,这是一段Java代码有效,因为使用了一个可能不应该被允许的字符,但是。
for (char ch = 0; ch < Character.MAX_VALUE; ch++)
if (Character.isJavaIdentifierPart(ch) && !Character.isJavaIdentifierStart(ch))
System.out.printf("%04x <%s>%n", (int) ch, "" + ch);
大多数IDE将帮助初学者编写遵循约定的代码。唯一的问题是大多数开发人员不知道如何充分利用他们的IDE。 ;)
答案 1 :(得分:2)
嗯,我个人认为不执行约定的原因仅仅是因为它在技术上并不是真正必要的。反例:例如在Java中,您必须将类文件命名为类,因为Java类加载器无法加载它。将这些检查构建到编译器中会使源代码膨胀,正如名称所示,编译器通过解析源文件和检查语法将源代码转换为机器代码/字节代码等。检查类是以大写还是小写字母开头,这根本不是编译器的工作。
当然,如果编程语言与语言的语法规则相匹配,那么编程语言可以通过不执行约定来为您的代码设置样式,从而为您提供一定程度的自由。
答案 2 :(得分:2)
从Java语言设计者的角度来看:有没有什么好的理由在语法和命名约定之间留下一个不应该被违反的空白?
是。 &#34;决不&#34;是一个强有力的词。
该语言有要求和建议。 The language specification for identifiers是必需的。但那些强有力的命名惯例是建议。
对于标识符的某些定义,编译器必须将它们识别为标记。让这个定义比规范更宽松,为我们提供了一些超出常规的案例的自由。
是否有任何有意义的用例(类,方法,字段,变量)违反惯例但超出惯例有意义?
是。 Java程序可以与其他语言进行交互,这些语言有不同的约定。
代码转换
有时,当手动转换来自其他语言的代码时,保留原始案例更容易,也更容易理解。
代码生成
有时我们会从不是为Java编写的规范中生成代码。例如,我们可能会从WSDL文件生成代码,或使用SWIG生成包装器。
代码包装
某些Java方法可以包装外部函数。例如,JNA允许使用本机函数的名称和签名定义接口。
JVM语言
Multiple languages可以在Java虚拟机上运行。这些其他语言有自己的约定。可以在单个程序中混合语言。走出会议之外可能需要进行互动。
答案 3 :(得分:2)
好吧,如果我在标识符中使用了一些中文字符,那么就没有大写/小写的情况:)所以不能总是强制执行约定。
当然,打赌99.9%的Java代码是英文的,这是非常安全的。你也可能会争辩说,只有一些字符集可以限制执法。
我同意这个命名约定变得至关重要,应该严格遵守。不符合约定的java源代码实际上是不可理解的。
答案 4 :(得分:1)
我想这就是为什么它只是约定而不是规则...我不明白为什么要强制执行,还有许多其他约定没有强制执行(例如将构造函数放在其他方法之前,将公共方法放在私有之前方法和更多),它将是太严格(至少在我看来)强制执行它。 我可以想到一个案例,你不希望强制执行这个约定 - 将consts变量写成大写也是很常见的 - 只是一个惯例。
在任何情况下,我认为在大多数IDE中,您可以将其配置为在违反此类约定时发出警告。这可以帮助你我猜