第1章:命名规范
1.1 类名以package名称为前缀
package com.taobao.ic.web.module.screen.user;
public class
UserView {
}
---->>>>
public class
View {
}
|
1.2 异常类的类目不以Exception为后缀
1.3 长整形数值以小写'l'结尾
long userId=23l;
---->>>>
long userId=23L;
|
1.4 函数名称和类名相同
1.5 函数的参数名和其覆盖的函数名称不一致
1.6 变参的方法不允许传入原始数据类型的数组
1.7 标准变量名称
1.8 方法的参数不要超过5个
private Result
updateItem(BidItemVO vo, String sellerID, String itemID, List lvo, String hasUpload, long limitCode)
{
}
---->>>>
public Result
getAuctionDetail4Mercury(ItemDetailQuery query) {
}
|
1.9 太复杂的判断条件,比如有多个and、or的情况,加括号分类,分行
第2章:代码风格
2.1 C语言风格的数组创建
String
matrix[] = null ;
---->>>>
String[]
martrix = null ;
|
2.2 声明包含javadoc错误
2.3 一次声明多个变量
String
nick, realName;
---->>>>
String
nick;
String
realName;
|
2.4 合理地进行参数校验
public boolean
isMatchMD5(String source, String encodedStr) {
if (StringUtil.isBlank(source)
|| StringUtil.isBlank(encodedStr)) {
return false ;
}
if (!CodesUtil.encodeMD5(source).equals(encodedStr))
{
return false ;
}
return true ;
}
|
2.5 对用户提交的内容进行HTML的过滤
StringUtil.escapeSpecialHTML(mailtext, true );
|
2.6 在已有的类中增加方法,如果这个类不是自己创建的,建议加上作者,时间,注释。
/**
*
根据订单号获取订单详情
*
*
@author <a href="mailto:zhenbei@taobao.com">震北</a>
*
@since 2008-6-9 下午03:44:04
*
*
@param orderIdStr 订单号串:如:123 or 123:456
*
@param userId
*
@return
*/
Result
getOrderDetail(String orderIdStr, Long userId);
|
2.7 在已有的方法中加入条件分支或者其他业务逻辑,一定要注释
if (ucBaseDO
== null ||
ucBaseDO.isGradeNormal()) {
if (user.isRegieUser())
{
UserCardBaseDO
mallVipCardDO = this .userCardManager.findMallVIPCard(query.getLoginUserId(),
user.getUserId(), query.getTrackNick());
if (mallVipCardDO
!= null )
{
if (ucBaseDO
== null )
{
ucBaseDO
= mallVipCardDO;
} else if
(mallVipCardDO.getCurGradeIndex() > ucBaseDO.getCurGradeIndex()) {
ucBaseDO
= mallVipCardDO;
}
}
}
}
|
2.8 DO要尽可能利用自身的数据完成业务逻辑
2.9 避免无用的代码
2.10 方法的注释中,参数的说明和返回值的说明要写详细
/**
*
检查字符串是否为<code>null</code>或空字符串<code>""</code>。
*
*
StringUtil.isEmpty(null) = true
*
StringUtil.isEmpty("") = true
*
StringUtil.isEmpty(" ") = false
*
StringUtil.isEmpty("bob") = false
*
StringUtil.isEmpty(" bob ") = false
*
*
*
@param str 要检查的字符串
*
*
@return 如果为空, 则返回<code>true</code>
*/
public static
boolean
isEmpty(String str) {
return ((str
== null )
|| (str.length() == 0 ));
}
|
2.11 在程序的分支和复杂的逻辑处写详细的注释
2.12 DTO的每个属性要给出完整的注释
2.13 不可以将自己新编写的代码和其它代码一起格式化,developer只需要将自己新编写的代码进行格式化后提交
第3章:控制流程
3.1 if-else操作更改为三元操作符(?:)
if (foo()){
return bar();
} else {
return foobar();
}
---->>>>
return foo()?bar():foobar();
|
3.2 多余的if判断
if (foo()){
return true ;
} else {
return false ;
}
---->>>>
return foo();
|
3.3 接口调用是否进行了超时设置
第4章:异常处理
4.1 捕获一般异常
4.2 finally中包含return语句
4.3 catch语句中的throw语句忽略了已经捕获的错误
catch (SQLException
e) {
throw new
ManagerException( "数据库异常" );
}
---->>>>
catch (SQLException
e) {
throw new
ManagerException(e);
}
|
4.4 不允许捕获IllegalMonitorStateException
4.5 捕获所有Exception时不应忽略对RuntimeException的处理
4.6 try语句嵌套
4.7 慎重抛出异常
4.8 DAO和Manager大多直接抛出异常,AO捕获进行翻译和记录日志
4.9 不允许捕获异常而不做任何操作
4.10 如果使用log.warn记录跟踪调试信息,一定要注意量的问题
4.11 Log.xxxx(‘xxx’, exception),第二个参数才是异常
4.12 在log.debug前使用log.isDebugEnable
4.13 系统调试过程中写的日志,在提交时要去掉
第5章:Class变量
5.1 匿名类包含太多的方法
5.2 覆盖equals方法且没有在其中最终调用super.equals()的类必须同时也覆盖hashCode方法
5.3 类继承java.lang.Object
public class
User extends Object
{
}
---->>>>
public class
User {
}
|
5.4 实现Cloneable接口的类必须覆盖Object.clone方法。
5.5 Class代码中包含其子类
5.6 类的继承层次太深
5.7 类包含太多的构造函数
5.8 类包含太多的属性
5.9 类包含太多的方法
5.10 class没有package声明
5.11 实现Comparator接口的类应该实现Serializable接口
5.12 返回类型为Boolean的方法中不允许显式返回null
5.13 Hessian接口调用让系统不依赖于其他系统
5.14 对于发消息通知用户的过程最好使用异步方式
第6章:函数变量
6.1 返回类型为数组却可能返回null的时候,考虑返回尺寸为0的数组,而非null
6.2 函数有多个return语句
6.3 函数包含太多的参数
6.4 过度复杂的函数
6.5 throws语句中不必要的exception
public void
openFile(String fileName) throws IOException,
SQLException {
}
---->>>>
public void
openFile(String fileName) throws IOException
{
}
|
6.6 equals方法中应判断传入对象是否为null
第7章:变量度量
7.1 在for循环中对循环因子赋值
for ( int i= 0 ;i< 30 ;i++)
{
.....
i
= i + 2 ;
}
应该避免这样的代码
|
7.2 给函数参数赋值
public void
findWife(User user) {
user
= getWife(user.getId());
......
return user;
}
---->>>>
public void
findWife(User user) {
User
wife = getWife(user.getId());
......
return wife;
}
|
7.3 不应用==或!=(而非equals)判断String
7.4 不允许用==(而非isNaN)判断NaN
7.5 不必要的局部变量
User
user = findUserByNick(nick);
return user;
->
return findUserByNick(nick);
|
7.6 重复使用局部变量
String
nick = getUserNick(userId);
....
nick
= getUserRealName(userId);
....
---->>>>
String
nick = getUserNick(userId);
....
String
realName = getUserRealName(userId);
....
|
7.7 合理使用常量,尽量避免出现硬编码(写死的)数字、字符串
7.8 使用包装类型
第8章:Java 7
8.1 for循环使用'for each‘代替
List<Rule>
rules = new ArrayList<Rule>();
for ( int i
= 0 ;
i < rules.size(); i++) {
Rule
rule = rules.get(i);
...
}
---->>>>
for (Rule
rule : rules) {
...
}
|
8.2 indexOf()可以使用contains()代替
if (name.indexOf( "-" )!=- 1 )
{
...
}
---->>>>
if (name.contains( "-" ))
{
...
}
|
8.3 不必要的装箱操作
8.4 不必要的拆箱操作
第9章:性能
9.1 String.equals("")
if (userName.equals( "" ))
{
...
}
---->>>>
if (userName.length
== 0 ))
{
...
}
|
9.2 使用StringBuilder而不是StringBuffer
StringBuffer
content = new StringBuffer();
---->>>>
StringBuilder
content = new StringBuilder();
|
9.3 String变量的size()==0可以使用isEmpty()替换
if (userName.size()== 0 )
{
}
---->>>>
if (userName.isEmpty())
{
}
|
9.4 手动拷贝数组
String[]
array1 = new String[]{};
String[]
array2 = new String[]{};
for ( int i
= 0 ;
i < array1.length; i++) {
array2[i]
= array1[i];
}
---->>>>
System.arraycopy(array1, 0 ,
array2, 0 ,
array1.length);
|
9.5 避免在循环中使用“+”拼接字符串。
String
s = "" ;
for ( int i
= 0 ;
i < field.length; ++i) {
s
= s + field[i];
}
StringBuffer
buf = new StringBuffer();
for ( int i
= 0 ;
i < field.length; ++i) {
buf.append(field[i]);
}
String
s = buf.toString();
|
第10章:安全
10.1 访问系统属性
10.2 调用Runtime.exec()时使用非常量字符串
10.3 不安全的随机数生成规则
10.4 不能相信客户端的校验,服务器端仍要校验
10.5 在单例的类中谨慎使用成员变量
10.6 更新、删除操作,一定要校验操作人是否有对操作数据的操作权限
10.7 保证程序是线程安全的
第11章:资源管理
11.1 I/O资源打开后没有安全关闭
11.2 JDBC资源打开后没有安全关闭
11.3 Socket打开后没有被安全关闭
11.4 资源的使用要及时释放
第12章:线程
12.1 不允许将Calendar用于类的静态成员
12.2 不允许将DateFormat用于类的静态成员
12.3 延迟初始化的类成员应声明为volatile
12.4 不允许在持有锁的时候调用Thread.sleep()
12.5 不允许在Boolean对象上使用synchronized关键字
12.6 wait应置于条件循环中是使用,wait前检查所等待的条件已经满足,并避免意外唤醒的影响
第13章:代码成熟度
13.1 clone()方法出现在非Cloneable类中
13.2 Abstract method call in constructor
public User()
{
abstractMethod1();
this .name= "leijuan" ;
}
public void
abtractMethod1() {
if ( this .name.equals( "leijuan" ))
{
}
}
|
13.3 通过对新实例访问静态变量
if (shop.getType()
== shop.B2C_Type) {
...
}
---->>>>
if (shop.getType()
== Shop.B2C_Type) {
...
}
|
13.4 给变量赋null值
13.5 调用printStackTrace()
catch (SQLException
e) {
e.printStackTrace();
}
---->>>>
catch (SQLException
e) {
log.error( "sql
error" ,e);
}
|
13.6 依恋情节
13.7 文件分隔符硬编码
13.8 Overridable method call in constructor
13.9 Serializable类没有包含serialVersionUID属性
13.10 String相等判断应使用'equals()',而不是’==‘
if (user.getName()
== user.getRealName()) {
}
---->>>>
if (user.getName().equals(user.getRealName())
{
}
|
13.11 无用的赋值操作
13.12 JDBC ResultSet的索引为0
13.13 使用sun package下的类
13.14 equals()和hashCode()不成对出现
第14章:Java Collection
14.1 集合变量的类型为具体类,而不是接口
ArrayList
users = new ArrayList();
---->>>>
List
users = new ArrayList();
|
14.2 过度类型强制转换
printUsers((ArrayList)getUsers());
---->>>>
printUsers((List)getUsers());
|
第15章:单元测试
15.1 使用test4j进行单元测试
15.2 service层必须做单元测试,web层可以根据情况确定
15.3 单元测试覆盖率必须在60%以上(第一阶段)
15.4 各单元测试类继承自BaseTester
@Test
@SpringApplicationContext ({ "test/data-source.xml" , "test/spring-context.xml" })
public class
BaseTester extends JTester
{
}
|
15.5 单元测试环境参考lifeix-demo/demo-test例子
15.6 单元测试代码集中在单独的子工程中,实现代码不同业务逻辑的代码的高度隔离
第16章:MyBatis
16.1 ORM使用MyBatis完成
16.2 接口命名为 XxxMapper
public interface
ContextPhotoMapper {
|
16.3 参数传递不要使用Map
16.4 使用注解的方式绑定参数命名
public List<ContextPhoto>
findByPage( @Param ( "start" )
Integer start, @Param ( "limit" )
Integer limit);
|
16.5 MyBatis的配置文件需要指定sqlSessionFactory
< bean id = "firsttimes-sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean" >
< property name = "dataSource" ref = "dataSource" />
</ bean >
< bean id = "contextPhotoMapper" class = "org.mybatis.spring.mapper.MapperFactoryBean" >
< property name = "mapperInterface" value = "com.lifeix.firsttime.module.mapper.ContextPhotoMapper" />
< property name = "sqlSessionFactory" ref = "firsttimes-sqlSessionFactory" />
</ bean >
|
16.6 一个Mapper的java文件和xml文件名称必须相同,分别放到不同目录下去
第17章:Velocity
第18章:Cookie
第19章:其它