“Java源文件规约”的版本间的差异
(→前言) |
(→前言) |
||
| (未显示同一用户的3个中间版本) | |||
| 第7行: | 第7行: | ||
本文档没有阐明各个项目元素的命名规范,这部分请参考:《[[平台代码规约]]》。 | 本文档没有阐明各个项目元素的命名规范,这部分请参考:《[[平台代码规约]]》。 | ||
| − | 阅读本文档前请先阅读《[ftp://ftpuser@47.92.209.132/ | + | 阅读本文档前请先阅读《[ftp://ftpuser@47.92.209.132/Document/Ali_Java_Developer's_Guide.pdf 阿里巴巴Java开发手册.pdf]》,与本规约冲突的地方<span style="color:red">以本规约为准</span>。 |
== 结构规定 == | == 结构规定 == | ||
2019年7月18日 (四) 12:41的最新版本
前言
本文档是研发规范的一部分,阐述一般性Java源文件的结构规范。
本文档关注一般源代码文件的组成项目、项目之间先后顺序的规定,以及格式要求。
本文档没有阐明各个项目元素的命名规范,这部分请参考:《平台代码规约》。
阅读本文档前请先阅读《阿里巴巴Java开发手册.pdf》,与本规约冲突的地方以本规约为准。
结构规定
结构概览
- 文件头声明
- package行
- import块
- 类声明
- 静态成员变量 / Static Fields
- 静态初始化块 / Static Initialize
- public静态方法 / Public Static Methods
- 成员变量 / Fields
- 初始化块 / Initializer
- 构造器 / Constructors
- 成员方法 / Methods
- 非静态成员方法 / Static Methods
- 重载自Object的方法如toString(), hashCode() 和main方法
- 类型(内部类) / Types(Inner Classes)
同等的类型,按private, protected, public的顺序排列。
文件头声明
文件头注释需标明SVN版本替换标签与版权信息两部分内容,如:
/**
* $Id:$
* Copyright 2014-2017 Hebei Sinounited Technology Company Ltd. All rights reserved.
*/
package com.opensource.ap.security.service;在源码提交SVN服务器后,SVN版本替换标签信息将自动替换为文件名称、版本号、提交版本服务器时间、提交用户名等内容,如:
/**
* $Id: ApOrganService.java 210 2017-02-16 11:28:18Z Jades_He $
* Copyright 2014-2017 Hebei Sinounited Technology Company Ltd. All rights reserved.
*/
package com.opensource.ap.security.service;package行
package声明紧跟在文件头声明内容之后、Import块之前,与其后内容留一空行,如:
/**
* $Id: ApOrganService.java 211 2015-05-25 11:33:24Z Jades_He $
* Copyright 2014-2015 Hebei Sinounited Technology Company Ltd. All rights reserved.
*/
package com.opensource.ap.security.service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import块
import块在package行之后、类声明之前,与前后内容之间各留一空行。
静态导入(import static)在前,类导入在后。
静态导入内容必须精确到变量或方法、导入类必须精确到具体的类。
不同导入部分之间留一空行。
可使用Eclipse快捷方式ctrl + shirt + o自动完成。
/**
* $Id: ApOrganService.java 212 2015-05-25 11:39:47Z Jades_He $
* Copyright 2014-2015 Hebei Sinounited Technology Company Ltd. All rights reserved.
*/
package com.opensource.ap.security.service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.opensource.ap.entity.ApOrganEntity;
import com.opensource.ap.security.constant.SecurityConstant;类声明
包括类Java Doc注释和类声明行两部分,注释在前,声明在后。
类注释在import块之后,与其之间有一空行类注释需填写类摘要说明、@author、@since等必选信息,根据需要填写@version等信息。
作为API提供的类,应在注释中简单说明如何使用,以及其它有助于快速、正确使用它的有关信息。
类注释后紧跟类声明,其间无空行,如:
/**
* 依照研发部《Java源文件规范》进行创建,用于提供一个示例。
*
* <p>
* 在《Java源文件规范》中将使用到这个源文件的代码片段,形象说明规范要点。
* </p>
*
* <p>
* 如果注释中出现和HTML冲突的字符,比如大于号{@literal >},小于号{@literal <},请使用@literal处理。
* </p>
*
* @author Jades.He
* @since 2015年5月25日 下午8:11:59
*/
public class JavaSourceDemo {静态成员变量&静态初始化块
final域在前,非final域变量在后
private在前,public在后。
域的初始化块紧接在域声明后,分开使用初始化块,不合成一起。
综合初始化块,在所有域和静态初始化块后:
public class JavaSourceDemo implements Serializable {
/** serialVersionUID */
private static final long serialVersionUID = 1L;
/** Logger */
protected static final Logger logger = LoggerFactory.getLogger(JavaSourceDemo.class);
/** 静态常量 */
public static String VERSION;
static {
VERSION = "1.0.0";
}public静态方法
public静态方法在成员变量和构造器之前。
main方法在所有静态方法之前。
main方法要对输入参数格式做注释说明。
成员变量&实例初始化块
成员变量应定义为private或protected,谨慎使用public。
成员变量应提供简单的/** */单行注释,标明其中文名称或职责功能。
成员变量与成员变量之间空一行。
/** 用户名 */
private String username;
/** 密码 */
private String password = "123";构造器
构造器在实例成员后,实例方法前;
根据Java语言规范,当类没有声明任何构造器时,Java认为其默认具有一个无参构造器;
当类明确声明了构造器,Java不再为类默认添加任何构造器;
有多个构造器时,参数少的在前,多的在后。 构造器的注释应该注重说明意图以及参数对对象的影响; 构造器的个数应该控制在有限个数内,否则应该使用Builder模式、静态工厂方法模式等替代方案(请参见<Effective Java>);
实例方法顺序
一般原则:
getter/setter方法,:getter在前,setter在后,使用eclipse自动生成Java Doc注释即可。
- private方法
- protected方法
- package-protected方法
- public方法
对一组功能类似的方法,short-cut的方法在前,复杂的方法在后。
常用方法排序示例:
- page 方法
- list 方法
- get 方法
- insert 方法
- update 方法
- delete 方法
实例方法的声明
对abstract方法实现的,重写父类方法的,必须声明@Override;
对有相同参数个数的重载方法(overloaded)或称多态方法的,应该非常谨慎,改个名字最好;
对public、protected一定要写Java Doc注释,而且是有效的。
非public静态方法
原则上:所有非public静态方法应该在所有实例方法之后,具名内部类前
这类静态方法往往是一些函数性、工具性的方法
特例:有些非public静态方法,是为一组功能相似或紧密的方法使用的,如果放在这些静态或实例方法后面更有助于代码阅读,应贯彻此特例。这类同于short-cut
请参考String.java的indexOf和lastIndexOf两个静态方法的位置。
注释规定
对public和protected的元素都必须写Java Doc注释:说明API意图/功能(第一行)、是否可用于多线程(默认不说明应该保证可用于多线程下)、是否是线程安全的(默认不说明应该保证线程安全) 、输入参数规格(@param)、输出规格(@return)、对象或参数处于某特定状态将抛什么异常(@throws),以及对使用该类或方法的前提条件以及后置条件进行说明(如有限制的话)
Java Doc注释不要过多陈述“代码的内部实现”,而应从使用者的角度进行陈述。
对public/protected元素而言,Java Doc说明甚至是最重要的资产。
对private方法,也应该简单说明一下其意图或功能,以便于后续维护。
类注释
见类声明
方法注释
方法注释需填写摘要说明、@author、@since等必选信息。
/**
*
* @param args
* @author Jades.He
* @since 2017年2月17日 上午9:10:12
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}失效代码注释
由/*...*/界定,标准的C-Style的注释。专用于注释已失效的代码。
/*
* Comment out the code
* String s = "hello";
* System.out.println(s);
*/代码细节注释
由//界定,专用于注释代码细节,即使有多行注释也仍然使用//,以便与用/**/注释的失效代码分开
除了私有变量外,不推荐使用行末注释。其他代码使用行首注释
class MyClass {
/** An end-line comment. */
private int myField;
public void myMethod {
// a very very long
// comment.
if (condition1) {
// condition1 comment
...
} else {
// elses condition comment
...
}
}
}其他规定
代码字符规定
源代码使用UTF-8进行编码,创建Java工程时应进行确认或调整。
请把Eclpse的默认环境设置为UTF-8
Eclipse -> General -> Workspace -> Text file encoding -> Other UTF-8
例外:properities文件请默认保持拉丁字符集,不可调为UTF-8或GBK
源代码换行符,明确调整为Unix方式
我们的开发人员普遍使用Window和Unix操作系统开发,为统一起见而规此定。
Eclipse -> General -> Workspace -> New Text file line delimiter -> Other Unix
代码长宽限制
Java方法代码长度避免超过120行(不含方法头的Java Doc注释)
Java源文件宽度禁止超过120英文字符的宽度 (请通过Eclipse等IDE进行设置控制,请注意中文字符的宽度大于英文字符,所以应使用Eclipse控制注释的宽度在100个以内)
每个Java代码行(不管是否折行了),在调用方可调整的情况下,禁止超过120个字符
违反以上规定,不仅仅妨碍了代码可读性的提高,往往也意味中代码在设计、开发上有相当的改进空间。应寻找时间改善,提升代码设计质量、可维护性。
代码折行策略
在分隔符号后折行
逗号(,) 分号(;) 赋值号(=)
Eclipse格式化可以自动调整,使符合此规范。
在运算符号前折行
算术符号(+, -, *),关系运算符(&&, ||), ...
Eclipse格式化可以自动调整,使符合此规范。
考虑使用行注释符//
IDE的折行策略大部分是可行的,但是也有一些折行,IDE工具处理得很糟糕。
通过行注释符可以强制改变IDE自动折行策略,使按照我们定义的方式折行。
可在 // 后,写 NL (=new line),以明确告知读者,这里用于折行
MemberDealerAcct memberDealerAcct = memberDealerAcctDao.selectByPrimaryKey( // NL
memberFeeDtl.getMemberDealerAcctId());代码缩进策略
使用空格缩进,宽度默认为2个字符
Eclipse格式化可以自动调整,使符合此规范。
Annotation标注风格
| 请使用 | 不使用 |
@Override
public String toString() {
return xxx;
}
// 如果有多个Annotation,每个一行 |
@Override public String toString() {
return xxx;
}
public @Override String toString() {
return xxx;
} |
泛型使用规定
按照《Effective Java》建议,在新代码中应该使用泛型;
对List,Set, Map等集合类,我们强制使用;
对兼容旧代码的,实在没办法处理的,必须使用@SuppressWarnings("uncheck")处理,但禁止在Class级别使用,只能使用在方法或变量级别;
提交到版本库的代码不能出现warnnings警告
方法的命名规则
方法命名的基本原则:见名知意 一般的方法名采用两个单词动宾结构形式的名称,两个单词之间不要带其它符号,第二个单词的首字母大写,其它的都小写。 如:findUser(int userId)、deleteUser(int userId) 只有一个动词形式的方法名不推荐使用。 不容易看明白的方法名或有歧义的方法名可采用多单词的形式,每两个单词之间不要带其它符号,从第二个单词开始,每个单词的首字母大写,其它的都小写如:findUserByUserId(int userId)、findUserByUserIdAndYear(int userId, int year)
odds & ends
- 一行文本行,不要有2个代码行:argv++; argc--; // AVOID!
- 对单独的if-else里面的语句,强制使用括号
- 覆盖或实现父类的方法必须标明注解:@Override
- 判断一个对象不为空时不使用
!=null来判断,应使用如下方式:
if (!(entity == null)) {
// TODO
}- 代码中的
TODO必须有实际意义,IDE自动生成的需删除:
public static void main(String[] args) {
// 下一行自动生成的TODO必须删除!
// TODO Auto-generated method stub
}