Coding Standards - Develop good Java coding habits

Recently, in order to organize the content of the company's coding standards, the coding standard plug- 2017in was 阿里巴巴released in 2018. It is strongly recommended that everyone install and use it. Good coding habits are the ladder to success.

The QR code of the technical group is at the bottom, welcome to join the group to learn! ! !

Short book complete set of documents and source code analysis

Topic Topic name Thematic description
001 Spring Boot core technology Explain some core components of SpringBoot at the enterprise level
002 Spring Cloud core technology Comprehensive explanation of the core technologies of Spring Cloud
003 QueryDSL core technology Comprehensively explain the core technology of QueryDSL and integrate SpringDataJPA based on SpringBoot
004 SpringDataJPA core technology Comprehensive explanation of the core technology of Spring Data JPA

Documentation directory

  • Annotation Specification
    • class annotation
    • method annotation
    • line-level comments
    • DTO/Param annotations
  • Coding Standards
    • naming style
    • constant definition
    • code format
    • OOP protocol
    • Collection processing
    • control statement
  • exception log specification
    • exception handling
    • log protocol

1. Annotation specification

class annotation

Classes and class attributes use Javadocspecifications. The class describes the main function of the class, and the annotations are as detailed as possible. It is recommended to use @seeannotations to mark the places where the class is used, and the class attributes describe the storage content of the attribute in detail.
类注释示例:

/**
 * 统一资源Aop切面定义
 * 根据自定义注解配置自动设置配置的资源类型到指定的字段
 * @author:于起宇 <br/>
 * ===============================
 * Created with IDEA.
 * Date:2017/12/15
 * Time:14:05
 * ================================
 */

类属性注释示例

/**
 * 资源处理业务逻辑
 */
Autowired
ResourcePushService resourcePushService;

method annotation

Interface methods, implementation class methods, abstract methods, etc., describe the main function of the method in detail, and describe the main process steps of the method as much as possible. Each parameter of the method definition needs to be described in detail. It is recommended to add a description of the method return value.
方法注释示例:

    /**
     * 资源设置切面方法
     * 拦截配置了@ResourceMethod注解的class method
     * cglib仅支持class 方法切面,接口切面不支持
     * @param proceedingJoinPoint 切面方法实例
     * @param resourceMethod 方法注解实例
     * @return 原方法返回对象
     */
    @Around(value = "@annotation(resourceMethod)")
    public Object resourcePutAround(ProceedingJoinPoint proceedingJoinPoint, ResourceMethod resourceMethod)
        throws Throwable
    {
        //...
    }

If it is a business logic method annotation, it is recommended to add steps as follows:

    /**
     * 创建帖子
     * - 转换参数实体为
     * - 保存帖子基本信息
     * @param param 创建帖子请求参数实体
     * @return 帖子编号
     * @throws LogicException
     */
    public String create(CreateTopicParam param) throws LogicException {
        //...
    }

In the above code, the -separator represents the main execution steps, and each step starts with the -separator. If there is logical branch processing in the method, please see below 行注释.

line comment

Line-level comments are generally used in methods, and are divided into single-line comments and multi-line comments. Single-line comments use //settings, and multi-line comments use /* */settings, as shown below:
单行注释:

// 执行方法,获取返回值

多行注释

/*
 * 执行方法,获取返回值
 * 获取返回值进行后续逻辑处理
 */

DTO/Param annotations

In the actual development process, the entity corresponding to the database is not allowed to directly add some additional fields, that is, it is forbidden to add fields that are not in the entity corresponding to the data table. In this case, we need to define it DTO/Param.

DTO annotation

DTOIt is the definition of the data return entity. If we need to associate the data of other tables and return it to the front end when querying the database, then we can create XxxDTOit. Note: DTOall uppercase, only the main table entity that inherits the query logic can complete the addition of additional fields. To add detailed comments for each additional field javadocas follows:

/**
 * 帖子列表数据转换实体
 * @author:于起宇 <br/>
 * ===============================
 * Created with IDEA.
 * Date:2018/1/8
 * Time:10:52
 * ================================
 */
@Data
public class TopicListDTO
        extends CommunicationTopicInfoEntity {

    /**
     * 用户昵称
     */
    private String userNickName;
    /**
     * 所属机构名称
     */
    private String orgName;
    //...
}
Param Notes

For the interface and the backend, some parameters are generally accepted when accepting requests. At present, our system is completely separated from the front desk, so the backend is actually an interface in disguise. It is also mentioned above DTOthat data entities are not allowed to add additional parameters. Our parameters are also It is impossible to be all fields in the data entity. At this time, the corresponding parameter entity needs to be created XxxParam. All fields in the parameter entity need to be javadocannotated, as shown below:

/**
 * 查询帖子列表
 * - 用于查询自己、他人、关键字、首页帖子请求参数
 *
 * @author:于起宇 <br/>
 * ===============================
 * Created with IDEA.
 * Date:2018/1/8
 * Time:10:31
 * ================================
 */
@Data
public class SelectTopicParam extends PagerParam {
    /**
     * 用户编号
     */
    private String userId;
    /**
     * 查询关键字
     */
    @Length(max = 30)
    private String keyWord;
}

2. Coding Specifications

naming style

  1. Names in the code cannot begin with an underscore or dollar sign, nor can they end with an underscore or dollar sign.

错误示例:

_name / name_ / $name / name$ / __name / name__
  1. It is strictly forbidden to use Chinese pinyin and English for naming, and it is not allowed to use Chinese names directly.

错误示例

WenZhang[文章] / WenZhangInfo[文章信息] / getTopicLieBiao()[获取文章列表] / int 数量 = 0
  1. Class name usage UpperCamelCasestyle DTO, VOexcept ,

错误示例

QRCode / UserInfoDto / XMLService

正确示例

QrCode / UserInfoDTO / XmlService
  1. Method names, parameter names, member variables, and local variables should be used in a unified lowerCamelCasestyle, and must use camel case naming.

错误示例

localvalue / GetUserInfo() / userid

正确示例

localValue / getUserInfo() / userId
  1. The names of constants are all uppercase, and the words are separated by underscores to fully express the meaning. The name can be too long.

错误示例

MAX_COUNT / NAME

正确示例

MAX_STOCK_COUNT / DEFAULT_ORG_NAME
  1. The abstract class is named with Abstractor Baseat the beginning, the exception class is named with the Exceptionend, and the test class is named with the full name of the class to be tested + Test.

正确示例

AbstractCodeMessageService / BaseCodeMessageService / LogicException / UserControllerTest
  1. The package name is uniformly lowercase, and each delimiter must be an English word with natural semantics. In addition, the package name uniformly uses the singular meaning. If the plural meaning is required, it can be reflected in the class name.

正确示例

com.sanmi.framework.core / com.sanmi.framework.orm
  1. Avoid non-standard abbreviations and avoid unclear expression of word meanings.

错误示例

AbstractClass = > AbsClass
condition => condi
  1. Do not add any modifiers to the methods and properties in the interface (and do not add public), in order to keep the code concise, add effective javadoccomments.

错误示例

public abstract void commit();

正确示例

void commin(); / String COMPANY_NAME = "sanmi";
  1. For Servicethe DAOimplementation class suffix when naming with the class, it must Implend with Mapperan implementation class. There is no implementation class for the interface, so no need to deal with it.

正确示例

UserInfoService / UserInfoServiceImpl
  1. Enumeration class names are uniformly Enumsuffixed, enumeration member names need to be all uppercase, and words are separated by underscores.

正确示例

枚举名称 => UserStatusEnum
成员名称 => ENABLE / DISABLED / DELETE
  1. The naming convention of each layer method The naming convention of the
    Service/DAO/Mapperlayer method is as follows:
    • methods to get a single object are getprefixed with
    • Methods to get multiple objects are listprefixed with
    • The method to get the statistic is countprefixed with
    • Insert method is used save / insertas a prefix
    • delete method is used delete / removeas prefix
    • Modify the method to use updateas a prefix

constant definition

  1. Do not allow any magic values ​​(constants not pre-defined) to appear directly in the code

错误示例

if("enable".equals(user.getStatus())) { 
   //.. 
}
  1. Use wrapper types instead of primitive data types

正确示例

Integer => int
Double => double
Long => long
...
  1. If the constant changes in only one scope, use enuminstead of defining

正确示例

@Getter
public enum  UserBzEnum
{
    /**
     * 普通用户
     */
    APP_USER("0"),
    /**
     * 月嫂
     */
    NANNY("1"),
    /**
     * 医生
     */
    DOCTOR("2")
    ;
    private String value;

    UserBzEnum(String value) {
        this.value = value;
    }
}

code format

  1. The usage convention of curly brackets, if the curly brackets are empty, they can be used directly {}without newlines; if the code is not empty, you need to:
    • No line break before opening brace
    • newline after opening brace
    • closing curly brace newline
    • If there are codes such as else after the closing curly brace, the line will not be wrapped; after the closing curly brace, the line must be wrapped.
  2. A space does not appear between the opening parenthesis and the character; nor does a space appear between the closing parenthesis and the character.
    错误示例:
if ( a == b )
  1. Spaces must be added between reserved words such as if / for / while / switch / do and parentheses
  2. A space is required to the left and right of any binary or ternary operator.

正确示例

 if (ValidateTools.isEmpty(uploadBackEntity) || ValidateTools.isEmpty(uploadBackEntity.getUploadUrl())) {
 //...
        }
  1. Use 4 spaces for indentation and prohibit the use of Tabcontrol characters.
  2. //There is one and only one space between line-level comments and the comment content.

正确示例

// 定义用户名
String userName = user.getName();
  1. The number of characters in a single line is not more than 120, and more than 120 characters need to be wrapped. The principles of line wrapping are as follows:
    • The second line is indented by 4 spaces relative to the first line, and no indentation is performed from the third line
    • Operators are wrapped together (eg: +)
    • .Symbols wrap together
    • When multiple parameters in a method call require a line break, do so after a comma.

正确示例

StringBuffer buffer = new StringBuffer();
// 超过120个字符的情况下,换行缩进4个空格,``.``和方法名一块换行
buffer.append("san").append("mi") ...
        .append("ke")
        .append("ji");
// 参数过多超120个字符时,在 , 后换行
method(args1, args2, args3, ...
args98, args99
)        
  1. When defining and passing in method parameters, multiple parameters must be followed by a space.
    正确示例:
method(args1, args2);
OOP protocol
  1. Avoid accessing static variables or static methods of this class through an object reference of a class, which will cause compiler parsing costs, and can be accessed directly with the class name. [The JVM heap, stack, and static code block parsing costs are different]
  2. All overriding methods must be @Overriderannotated
  3. For the interface that is being called externally or depends on the second-party library, it is not allowed to modify the method signature to avoid affecting the interface caller; if the interface is outdated, an @Deprecatedannotation must be added, and the alternative interface or alternative service must be clearly explained.
  4. Obsolete classes or methods are prohibited.
  5. Objectmethods that equalsare prone to throwing null pointer exceptions should use constants or deterministic objects to call equalsmethods.

错误示例

object.equals("test");

正确示例

"test".equals(object)
  1. For comparisons between all encapsulated classes of the same type, equalsmethods must be used.

说明: The assignment of the intencapsulated class Integerwithin the -128 ~ 127scope will be IntegerCache.cachegenerated in , and the value of this interval can be directly used for== comparison, but the value outside the interval will be created with the reference type, and objects cannot be used for comparison! 7. It is forbidden to write any business logic in the constructor. If there is business logic, please create a method to use it.==
init

Collection processing
  1. To use the method of converting a collection to an array, you must use a collection, and the toArray(T[] array)incoming array is the exact same type, and the size is the same list.size().

正确示例

List<String< list = new ArrayList();
list.add("jinan");
list.add("sanmi");
// 生成list长度的数组实例
String[] array = new String[list.size()];
// 执行集合转换数据
array = list.toArray(array);
  1. When using the utility class Arrays.asList()method, you cannot use the method related to modifying the collection, and the add / remove / cleanmethod will throw an exception.
  2. It is forbidden to operate foreachelements in the loop. Please use the elements in the way. If you operate concurrently, you need to lock the object.remove / addremoveIteratorIterator

正确示例

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String item = iterator.next();
    if (condition) {
        iterator.remove();
    }
}
control statement
  1. Within one switch, each is caseeither break / returnterminated with , or a comment stating that the program will continue to execute as casefar as the specific one; within one switchmust contain defaultcode blocks after all case, even if the business logic is empty!
  2. if / else / for / while / doBraces must be used in statements, even if there is only one line of code.

错误示例

if (condition) statements;

正确示例

if (condition) {
    statements;
}
  1. When expressing exception branches, use as little if / else ifnesting as possible, which can be modified to:
if (condition) {
    //...
    return object;
}
// 继续处理 else / else if 业务逻辑代码

If you have to use more than three layers of if / else iflogical judgment, you can change the code to 卫语句, 策略设计模式, 状态设计模式. The following is an example of a guard statement:

public void today() {
    if (isBuy()) {
        System.out.println("do something.");
        return;
    }
    if (isFree()) {
        System.out.println("do something.");
        return;
    }
    System.out.println("coding..");
}

In our system design, we generally use throw new XxxException();will return;instead, and all logic exception judgments are handled by custom business logic exceptions.

3. Exception log specification

unusual convention
  1. The ones defined in the Java class library can be pre-judged to avoid RuntimeExceptionand should not be used try {} catch(Exception e){}to deal with them.

错误示例

// 直接使用不确定对象
object.setXxx(value);

正确示例

// 判断非空后使用不确定对象
if (object != null) {
    //...
}
  1. The purpose of catching an exception is to handle it. Don't catch it but throw it away without handling it. If you don't want to handle it, please throw the exception to its caller. The outermost business user must handle the exception and convert the exception information. information that can be understood by the user.
  2. Some trycode blocks are placed in the transaction code. After the catch exception, if you need to roll back the transaction, you must pay attention to rollbackthe transaction.
  3. finallyThe code block must close the resource object and the Liu object, even if there is an exception try-catch.
  4. Cannot be used in finallycode blocks return.
  5. Please deliver business logic exceptions to the framework for processing, and we will use the business logic exception handling mechanism for business logic verification to be thrown to the framework for processing.

正确示例

if (condition) {
    throw new LogicException(ErrorCodeEnum.USER_NOT_FOUND);
}
log protocol
  1. The code cannot directly use the log system (Log4j, Logback) , but rely on the use of the APIlog framework . Using the log framework of the facade mode is conducive to the maintenance and unification of the log processing methods of various classes. :SLF4jAPI
    正确示例
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// 获取日志对象
private static final Logger logger = LoggerFactory.getLogger(Xxx.class);

The log object definition is generally defined in the initial stage of the project framework construction, and can be used directly. If you need to customize it, declare the log object in the above way.
2. For trace / debug / infothe log output of the level, you must use the placeholder method. If you do not use the placeholder but directly splicing it, it may cause the variable to nullcause a system exception, and if the log level does not match, although it will not be printed, it will be displayed. String concatenation is performed, which wastes server system resources.

正确示例

logger.debug("执行查询用户:{},基本信息。",user.getId());
  1. For the main parameters of the method, the corresponding value needs to be printed, which is convenient for the later log debugging project.

正确示例

public void today(String userId) {
    logger.debug("查询用户:{},今日任务完成进度",userId);
}
  1. The branch logic in the method needs to print the corresponding log information to facilitate the later log debugging project.

正确示例

if (condition1) {
    logger.debug("do something.");
} else if (condition2) {
    logger.debug("do other thing.");
}
  1. There are two types of system exceptions: 案发现场, 异常堆栈信息.

正确示例

logger.error(参数或对象.toString() + "_" + e.getMessage(), e);

write at the end

It is strongly recommended to IDEAinstall and use the international coding convention plug-in for development tools 阿里巴巴to lay the foundation for good coding habits.
Welcome to join the QQ technical exchange group and make progress together.
QQ technical exchange group

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324736137&siteId=291194637