Java编程中的一些常见问题汇总
本文列举了我在周围同事的Java代码中看到的一些比较典型的错误。显然,静态代码分析(我们团队用的是qulice)不可能发现所有的问题,这也是为什么我要在这里列出它们的原因。
如果你觉得少了什么,请不吝赐教,我会很乐意把它们加上。
下面列出的所有这些错误基本都与面向对象编程有关,尤其是Java的OOP。
类名
读下这篇短文“什么是对象”。类应该是真实生活中的一个抽象实体,而不是什么“validators”,“controller”, “managers”这些东西。如果你的类名以”er”结尾的话——那它就是个糟糕的设计。
当然了,工具类也是反模式,比如说Apache的StringUtils, FileUtils, 以及IOUtils。上面这些都是糟糕设计的代表。延伸阅读:OOP中工具类的替代方案。
当然,不要使用前缀或者后缀来区分类和接口。比方说,这些名字就是错误的:IRecord, IfaceEmployee, 或者RecordInterface。通常来说,接口名应该是真实生活中的实体的名字,类名应该可以说明它的实现细节。如果这个实现没有什么特别可说明的,可以把它叫作Default, Simple或者类似的什么。比如说:
class SimpleUser implements User {};
class DefaultRecord implements Record {};
class Suffixed implements Name {};
class Validated implements Content {};
方法名
方法可以返回值也可以返回void。如果方法返回值的话,它的名字应该能说明它返回了什么,比如说(永远也不要使用get前缀):
boolean isValid(String name);
String content();
int ageOf(File file);
如果它返回void,那么它的名字应该要说明它做了什么。比如:
void save(File file);
void process(Work work);
void append(File file, String line);
刚才提到的这些规则只有一个例外——JUnit的test方法不算。下面将会说到这个。
test方法的名字
在JUnit的测试用例中,方法名应该是没有空格的英文语句。用一个例子来说明会更清楚一些:
/**
* HttpRequest can return its content in Unicode.
* @throws Exception If test fails
*/
public void returnsItsContentInUnicode() throws Exception {
}
你的JavaDoc里的第一句话的开头应该是你要测试的那个类的名字,然后是一个can。因此,你的第一句话应该是类似于“somebody can do something”。
方法名也是一样的,只是没有主题而已。如果我在方法名中间加一个主题的话,我就能得到一个完整的句子,正如上面那个例子中那样:“HttpRequest returns its content in unicode”。
请注意test方法的名字是不以can开头的。只有JavaDoc里的的注释会以can开头。除此之外,方法名不应该以动词开头。
实践中最好将测试方法声明为抛出Exception的。
变量名
避免组合的变量名,比如说timeOfDay, firstItem,或者httpRequest。类变量及方法内的变量都是如此。变量名应该足够长,避免在它的可见作用域内产生歧义,但是如果可以的话也不要太长。名字应该是单数或复数形式的名词,或者是一个适当的缩写。比如:
List<String> names;
void sendThroughProxy(File file, Protocol proto);
private File content;
public HttpRequest request;
有的时候,如果构造方法要将入参保存到一个新初始化的对象中的时候,它的参数和类属性的名字可能会冲突。这种情况,我建议是去掉元音,使用缩写。
示例: