一  编码规范

1.1      命名规范

  1. 代码中的命名均不能以特殊字符(如下划线、$#符号)开始或结束。

反例: _name / #Object

2. 代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。

反例: toubao / lipei。

3. 类名使用UpperCamelCase风格,必须遵从驼峰形式。

正例:CommonUtils / BaseVo

4. 方法名、参数名、成员变量、局部变量都统一使用lowerCamelCase风格,必须遵从驼峰形式。

正例: orderService / getOrderService()

5. 常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。

正例: ZK_CONFIG_ROOTNODE

6. 抽象类命名使用Abstract或Base开头;异常类命名使用Exception结尾;测试类命名以它要测试的类的名称开始,以Test结尾。

7. 包名使用com.hetai.服务名.分层名。

正例: oauth系统的DAO, com.hetai.oauth.dao

8. 如果使用到了设计模式或具有明确职责,建议在类名中体现出具体模式或职责。

正例:ExecutorFactory / AbstractProducer

9. 各分层都需要接口和实现类,实现类用Impl作后缀与接口区别。

正例:OrderServiceImpl实现OrderService接口。

10. 枚举类名建议带上Enum后缀,枚举成员名称需要全大写,单词间用下划线隔开。

正例:枚举名字:PolicyIdTypeEnum,成员名称:ID_CARD/ PASSPORT。

11. 各层方法命名规范: 1) 查询的方法用get/ query做前缀。

2) 插入的方法用add 或insert做前缀。

3) 删除的方法用remove 或delete做前缀。

4) 修改的方法用modify/ update做前缀。

5) 获取多个对象的方法用List做结尾。

6)  获取统计值的方法用Count做结尾。

12. 全局常量类名建议“模块名Constant”。

正例:枚举名字:OrderConstant / CommonConstants。

13. 不要出现任何魔法值(即未经定义的常量)直接出现在代码中,应作常量声明。

反例: return "UNDERWRITE_RESULT_" + order_no;

1.2      OOP规范

  1. 对外暴露的接口签名,原则上不允许修改方法签名,避免对接口调用方产生影响。
  2. 序列化类新增属性时,请不要修改serialVersionUID字段,避免反序列失败;如果完全不兼容升级,避免反序列化混乱,那么请修改serialVersionUID值。

说明:注意serialVersionUID不一致会抛出序列化运行时异常。

  1. POJO类必须写toString方法。使用IDE的中工具:source> generate toString时,如果继承了另一个POJO类,注意在前面加一下super.toString。

说明:在方法执行抛出异常时,可以直接调用POJO的toString()方法打印其属性值,便于排查问题。

  1. 当一个类有多个构造方法,或者多个同名方法,这些方法应该按顺序放置在一起,便于阅读。
  2. POJO类中变量需要有get/set方法,通过使用IDE Generate自动生成。
  3. 循环体内字符串的联接方式,使用StringBuilder的append方法进行扩展。
  4. final可提高程序响应效率,声明成final的情况: 1) 不需要重新赋值的变量,包括类属性、局部变量。

2) 对象参数前加final,表示不允许修改引用的指向。

3) 类方法确定不允许被重写。

  1. 慎用Object的clone方法来拷贝对象。 说明:对象的clone方法默认是浅拷贝,若想实现深拷贝需要重写clone方法实现属性对象的拷贝
  2. 不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁

10. 使用entrySet遍历Map类集合KV,而不是keySet方式进行遍历。 说明:keySet其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的value。而entrySet只是遍历了一次就把key和value都放到了entry中,效率更高。如果是JDK8,使用Map.foreach方法。

正例:values()返回的是V值集合,是一个list集合对象;keySet()返回的是K值集合,是一个Set集合对象;entrySet()返回的是K-V值组合集合

11. 高度注意Map类集合K/V能不能存储null值的情况,如下表格:

集合类

Key

Value

Super

说明

Hashtable

不允许为null

不允许为null

Dictionary

线程安全

ConcurrentHashMap

不允许为null

不允许为null

AbstractMap

分段锁技术

TreeMap

不允许为null

允许为null

AbstractMap

线程不安全

HashMap

允许为null

允许为null

AbstractMap

线程不安全

1.3      控制规范

  1. 在一个switch块内,每个case要么通过break/return等来终止,要么注释说明程序将继续执行到哪一个case为止;

在一个switch块内,都必须包含一个default语句并且放在最后,即使它什么代码也没有。

  1. 在if/else/for/while/do语句中必须使用大括号,即使只有一行代码,避免使用下面的形式:if (condition) statements;
  2. 除常用方法(如getXxx/isXxx)等外,不要在条件判断中执行其它复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。
  3. 循环体中的语句要考量性能,以下操作尽量移至循环体外处理,如定义对象、变量、获取数据库连接,进行不必要的try-catch操作(这个try-catch是否可以移至循环体外)。
  4. 方法中需要进行参数校验的场景:    1)调用频次低的方法。

2) 执行时间开销很大的方法,参数校验时间几乎可以忽略不计,但如果因为参数错误导致中间执行回退,或者错误,那得不偿失。

3) 需要极高稳定性和可用性的方法。

4) 对外提供的开放接口,不管是RPC/API/HTTP接口。

5) 敏感权限入口。

1.4     格式规范

代码格式化参考<<eclipse编码规范约定>>

1.5      并发规范

  1. 获取单例对象需要保证线程安全,其中的方法也要保证线程安全。 说明:资源驱动类、工具类、单例工厂类都需要注意;
  2. 创建线程或线程池时请指定有意义的线程名称,方便出错时回溯;
  3. 线程资源必须通过线程池提供,不允许在应用中自行显式创建线程;
  4. SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为static,必须加锁,或者使用DateUtils工具类;

正例:注意线程安全,使用DateUtils。亦推荐如下处理:

private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {

@Override

protected DateFormat initialValue() {

return new SimpleDateFormat("yyyy-MM-dd");

}

};

说明:如果是JDK8的应用,可以使用Instant代替Date,LocalDateTime代替Calendar,DateTimeFormatter代替Simpledateformatter,官方给出的解释:simple beautiful strong immutable thread-safe。

  1. 高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁;
  2. 对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁。 说明:线程一需要对表A、B、C依次全部加锁后才可以进行更新操作,那么线程二的加锁顺序也必须是A、B、C,否则可能出现死锁;
  3. 使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown方法,线程执行代码注意catch异常,确保countDown方法可以执行,避免主线程无法执行至await方法,直到超时才返回结果。 说明:注意,子线程抛出异常堆栈,不能在主线程try-catch到;
  4. 避免Random实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed 导致的性能下降;

说明:Random实例包括java.util.Random 的实例或者 Math.random()实例。 正例:在JDK7之后,可以直接使用API ThreadLocalRandom,在 JDK7之前,可以做到每个线程一个实例。

  1. HashMap在容量不够进行resize时由于高并发可能出现死链,导致CPU飙升,在开发过程中注意规避此风险;

10. ThreadLocal无法解决共享对象的更新问题,ThreadLocal对象建议使用static修饰。这个变量是针对一个线程内所有操作共有的,所以设置为静态变量,所有此类实例共享此静态变量 ,也就是说在类第一次被使用时装载,只分配一块存储空间,所有此类的对象(只要是这个线程内定义的)都可以操控这个变量;

11. 单例模式推荐使用静态内部类方式实现, 参考com.hetai.common.util. PropertiesUtils;

二  异常规范

2.1 异常规范

  1. 不要捕获Java类库中定义的继承自RuntimeException的运行时异常类,如:IndexOutOfBoundsException / NullPointerException,这类异常由程序员预检查来规避,保证程序健壮性。

正例:if(obj != null) {...}

反例:try { obj.method() } catch(NullPointerException e){...};

  1. 异常不要用来做流程控制,条件控制,因为异常的处理效率比条件分支低;
  2. 捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容;
  3. 有try块放到了事务代码中,catch异常后,如果需要回滚事务,一定要注意手动回滚事务;
  4. finally块必须对资源对象、流对象进行关闭,有异常也要做try-catch;
  5. 不能在finally块中使用return,finally块中的return返回后方法结束执行,不会再执行try块中的return语句;
  6. 方法的返回值可以为null,不强制返回空集合,或者空对象等,必须添加注释充分说明什么情况下会返回null值。调用方需要进行null判断防止NPE问题。

说明:本规约明确防止NPE是调用者的责任。即使被调用方法返回空集合或者空对象,对调用者来说,也并非高枕无忧,必须考虑到远程调用失败,运行时异常等场景返回null的情况;

  1. 在接口设计中使用“返回错误码”,不要直接抛异常给到调用方;
  2. 定义时区分unchecked / checked 异常,避免直接使用RuntimeException抛出,更不允许抛出Exception或者Throwable,应使用有业务含义的自定义异常。推荐业界已定义过的自定义异常,如:DAOException / ServiceException等;

10. 避免出现重复的代码(Don’t Repeat Yourself),即DRY原则。 说明:随意复制和粘贴代码,必然会导致代码的重复,在以后需要修改时,需要修改所有的副本,容易遗漏。必要时抽取共性方法,或者抽象公共类,甚至是共用模块;

三  日志规范

3.1日志规范

  1. 应用中不要直接使用日志系统(Log4j、Logback)中的API,而应使用common包LogUtils中的API;
  2. 避免重复打印日志,浪费磁盘空间,在log4j.xml中设置additivity=false。

正例:<logger name="com.taobao.dubbo.config" additivity="false">;

  1. 异常信息应该包括两类信息:案发现场信息和异常堆栈信息。如果不处理,则往上抛。

正例:log.error(各类参数或者对象toString + "_" + e.getMessage(), e);

  1. 注意日志输出的级别,error级别只记录系统逻辑出错、异常等重要的错误信息。如非必要,请不要在此场景打出error级别;
  2. 日志级别按debug/info/warn/error四个级别输出,生产环境禁止输出debug日志;有选择地输出info日志;warn级别记录系统逻辑出错、异常等重要的错误信息;error级别只记录致命的、导致流程中止的错误或异常信息;
  3. debug/info级别的日志输出,必须使用使用占位符的方式,不建议使用条件输出形式。

说明:logger.debug("Processing trade with id: " + id + " symbol: " + symbol); 如果日志级别是warn,上述日志不会打印,但是会执行字符串拼接操作,如果symbol是对象,会执行toString()方法,浪费了系统资源,执行了上述操作,最终日志却没有打印;

四 工程规范

4.1工程规范

  1. 包名com.hetai.系统名,代码目录结构按以下表格:

模块

说明

resource

服务资源接口层,REST Resource,定义服务对外的REST 接口

service

服务业务层,在service组装业务逻辑

sao

服务远程方法调用层,封装调用其他服务接口

dao

服务持久化层,调用DB接口

vo

服务bean对象

common

服务公共代码,如工具类、常量类等

mapping

调用DB sql配置文件

extension

过滤器、拦截器filter/Interceptor

handler

线程处理实现类,参考《线程池使用指引》

  1. 配置文件目录结构按以下表格:

模块

说明

dev

开发环境配置文件

commit

测试环境(api)配置文件

commit_stg2

测试环境(api_stg2)配置文件

commit_app

测试环境(app)配置文件

formal

正式环境配置文件

formal_app

正式环境(app)配置文件

common

服务公共配置文件

五  安全规范

5.1 安全规范

  1. 隶属于用户个人的页面或者功能必须进行权限控制校验。 说明:防止没有做水平权限校验就可随意访问、操作别人的数据,比如查看、修改别人的订单;
  2. 用户敏感数据禁止直接展示,必须对展示数据脱敏。 说明:查看个人手机号码会显示成:137****5695,隐藏中间4位,防止隐私泄露;
  3. 用户输入的SQL参数严格使用参数绑定或者METADATA字段值限定,防止SQL注入,禁止字符串拼接SQL访问数据库;
  4. 禁止向HTML页面输出未经安全过滤或未正确转义的用户数据;
  5. 在使用平台资源,譬如短信、邮件、电话、下单、支付,必须实现正确的防重放限制,如数量限制、疲劳度控制、验证码校验,避免被滥刷、资损。 说明:如注册时发送验证码到手机,如果没有限制次数和频率,那么可以利用此功能骚扰到其它用户,并造成短信平台资源浪费;
  6. 发贴、评论、发送即时消息等用户生成内容的场景必须实现防刷、文本内容违禁词过滤等风控策略;
  7. ;
  8. 表单、AJAX提交必须执行CSRF安全过滤。

说明:CSRF(Cross-site request forgery)跨站请求伪造是一类常见编程漏洞。对于存在CSRF漏洞的应用/网站,攻击者可以事先构造好URL,只要受害者用户一访问,后台便在用户不知情情况下对数据库中用户参数进行相应修改;

转载于:https://www.cnblogs.com/heqianjiang/p/9843137.html

java代码开发规范相关推荐

  1. eclipse java代码某一行需要修改注释_看看这些Java代码开发规范吧!你好,我好,大家好!...

    作为一名开发人员,当你接手他人的项目时,且当你阅读他人的代码时,是有没有遇到脑袋充血,感觉Java要把你"送走"的感觉呢?我们在用Java开发技术进行开发前,一定要牢牢恪守Java ...

  2. java代码开发规范_java代码开发规范

    一  编码规范 1.1      命名规范 代码中的命名均不能以特殊字符(如下划线.$#符号)开始或结束. 反例: _name / #Object 2. 代码中的命名严禁使用拼音与英文混合的方式,更不 ...

  3. java json插件安装_IDEAL葵花宝典:java代码开发规范插件:GsonFormat插件将JSONObject格式的String 解析成实体...

    前言: GsonFormat插件主要用于使用Gson库将JSONObject格式的String 解析成实体,该插件可以加快开发进度,使用非常方便,效率高. 这个教程主要是学习IntelliJ IDEA ...

  4. Java 代码开发规范

    一.阿里巴巴Java开发手册下载 链接: https://pan.baidu.com/s/1VVsz1UIyOIJDXlzrBy6faQ?pwd=4skg 提取码: 4skg 复制这段内容后打开百度网 ...

  5. IDEAL葵花宝典:java代码开发规范插件 FindBugs-IDEA

     前言: 检测代码中可能的bug及不规范的位置,检测的模式相比p3c更多,写完代码后检测下 避免低级bug,强烈建议用一下,一不小心就发现很多老代码的bug. 使用步骤: 1):打开 Settings ...

  6. 【Java后台开发规范】--- 圈复杂度

    文章目录 前言 其他类型的规范 圈复杂度 提炼方法 if.else 卫语句 去else 策略模式 switch 循环嵌套 其他建议 前言 做Java开发的,大多数可能都有看过阿里的Java后台开发手册 ...

  7. java代码开发的通用规范

    文章目录 前言 一.命名风格 二.变量定义 三.代码格式 四.OOP 规则 五. 集合处理 六.控制语句 七.注释规约 八.异常处理 九.编码检查 十.编码安全 十一.其他约定 十二.SqlServe ...

  8. 长沙北大青鸟java 学费_长沙北大青鸟学校好不好 长沙北大青鸟实力学费一览表:Java代码编写规范(二)...

    原标题:长沙北大青鸟学校好不好 长沙北大青鸟实力学费一览表:Java代码编写规范(二) 文件名规范 1.一个Java源文件只能存储个Java类. 2.文件名与Java类名相同. 3.一个类文件的代码行 ...

  9. java 代码书写规范_代码书写规范和命名规范

    上一篇给大家分享了一下,关于文档编写的几个概念.这篇文章阐述如果编写代码书写规范以及命名规范文档.[以java语言为例] 1.代码书写规范 代码书写规范,能够让不同的人,写出相同风格的代码.很多人都看 ...

最新文章

  1. 图灵八月书讯 ——技术图书嘉年华
  2. react input[type='number']
  3. 每次hexo d部署后都要在github仓库上重新保存域名
  4. js端调用android端同步方法,JS怎样调用Android本地原生方法
  5. Android成长之路-实现简单动画
  6. 字符串数组 和 字符串指针 的区别
  7. 第8章 线性时间排序
  8. Struts2使用OGNL遍历各种map总结
  9. 企业管理软件随想-透视-包容,无形思想-有形方便
  10. plpgsql语句的兼容性
  11. sessionid如何产生?由谁产生?保存在哪里?
  12. 清理tomcat缓存
  13. python怎么过滤停用词_第6天:文本处理流程——停用词的过滤、正则化操作
  14. pcb板生产的工艺流程有哪些?
  15. 解决Tomcat中文乱码问题
  16. pycharm下载思维导图插件 idea mind map
  17. 你需要明白的索引和约束的前缀(AK,PK,IX,CK,FK,DF,UQ)
  18. opencv读图的坐标系转换问题
  19. 前端中的icon几种用法
  20. 西北工业大学国家精品课--流媒体课程

热门文章

  1. Licia:最全最实用的 JavaScript 工具库
  2. jQuery 对AMD的支持(Require.js中如何使用jQuery)
  3. codewars??? Is my friend cheating?
  4. 解决Jenkins的job启动tomcat时会在job结束时关闭问题
  5. ZeroMQ接口函数之 :zmq - 0MQ 轻量级消息传输内核
  6. IN和EXISTS的性能对比结论
  7. iPhone流量偷跑探秘
  8. asp.net faq: 在html文件中,用js获取session
  9. 一.JavaScript基础
  10. C++实现简单选择排序