我是靠谱客的博主 明亮翅膀,最近开发中收集的这篇文章主要介绍java编码规范判断题_Java编码规范(个人总结向),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

基本规范

禁止使用SUN包下的类,替换成公开的API,否则Maven不能打包

保持代码 google 风格

移除无用的代码和注释

【强制】类、类属性、类方法的注释必须使用 Javadoc 规范,使用/*内容/格式,不得使用// xxx 方式。

【强制】方法内部单行注释,在被注释语句上方另起一行。方法内部多行注释使用/* */注释,注意与代码对齐。

禁止JavaBean中的setter和getter里有逻辑代码

定时任务时间间隔不能小于5分钟,特殊情况需要告知技术经理,并经过技术经理同意

产品需求里的批量导入最多支持20条

【建议】POJO 类必须写 toString 方法,方便问题查询

【强制】所有的相同类型的包装类对象之间值的比较,全部使用 equals 方法比较

【推荐】类成员、方法、构造函数访问控制从严,正确使用 public、private、protected、final

【推荐】 表达异常的分支时, 少用 if-else 方式, 这种方式可以改写成:

说明: 如果非得使用 if()...else if()...else...方式表达逻辑, 避免后续代码维护困难, 请勿超过 3 层。

正例: 超过 3 层的 if-else 的逻辑判断代码可以使用卫语句、策略模式、状态模式等来实现。

if (condition) {

return obj;

}

// 接着写 else 的业务逻辑代码;

说明: 如果非得使用 if()...else if()...else...方式表达逻辑, 避免后续代码维护困难, 请勿超过 3 层。

正例: 超过 3 层的 if-else 的逻辑判断代码可以使用卫语句、策略模式、状态模式等来实现。

Service/DAO层方法命名规范

获取单个对象的方法用 select 作前缀。

获取多个对象的方法用 selectList 作前缀。

获取统计值的方法用 selectCount 作前缀。

插入的方法用 insert 作前缀。

删除的方法用 delete 作前缀。

修改的方法用 update 作前缀。

变量命名

力求语义表达完整清楚,不要嫌名字长。

包名

统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词

统一使用单数形式

常量定义

【推荐】常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量。

跨应用共享常量:放置在二方库中,通常是 client.jar 中的 constant 目录下。

应用内共享常量:放置在一方库中, 通常是子模块中的 constant 目录下。

反例: 易懂变量也要统一定义成应用内共享常量,两位攻城师在两个类中分别定义了表示“是”的变量:

类 A 中: public static final String YES = "yes";

类 B 中: public static final String YES = "y";

A.YES.equals(B.YES),预期是 true,但实际返回为 false,导致线上问题。

子工程内部共享常量:即在当前子工程的 constant 目录下。

包内共享常量:即在当前包下单独的 constant 目录下。

类内共享常量:直接在类内部 private static final 定义。

变量类型

【强制】 所有的 POJO 类属性必须使用包装数据类型。

【强制】 RPC 方法的返回值和参数必须使用包装数据类型。

【推荐】 所有的局部变量使用基本数据类型。

final关键字

【推荐】 final 可以声明类、成员变量、方法、以及本地变量,下列情况使用 final 关键字:

不允许被继承的类,如: String 类。

不允许修改引用的域对象,如: POJO 类的域变量。

不允许被重写的方法,如: POJO 类的 setter 方法。

不允许运行过程中重新赋值的局部变量。

避免上下文重复使用一个变量,使用 final 描述可以强制重新定义一个变量,方便更好地进行重构。

hashCode 和 equals的处理

只要重写 equals,就必须重写 hashCode。

因为 Set 存储的是不重复的对象,依据 hashCode 和 equals 进行判断,所以 Set 存储的对象必须重写这两个方法。

如果自定义对象作为 Map 的键,那么必须重写 hashCode 和 equals。(比如:String类)

集合处理

【强制】使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一样的数组,大小就是 list.size()。反例: 直接使用 toArray ()存在问题,此方法返回值只能是 Object[]类,若强转其它类型数组将出现 ClassCastException 错误。

【强制】使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。

说明: asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。

第一种情况: list.add("yangguanbao"); 运行时异常。

第二种情况: str[0] = "gujin"; 那么 list.get(0)也会随之修改。

String[] str = new String[] { "you", "wu" };

List list = Arrays.asList(str);

第一种情况: list.add("yangguanbao"); 运行时异常。

第二种情况: str[0] = "gujin"; 那么 list.get(0)也会随之修改。

【强制】不要在 foreach 循环里进行元素的 remove/add 操作。 remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁。

【强制】HashMap 初始化,initialCapacity = (需要存储的元素个数 / 负载因子0.75) + 1。

【推荐】使用 entrySet 遍历 Map 类集合 KV,而不是 keySet 方式进行遍历。如果是 JDK8,使用 Map.foreach 方法。

日期处理

如果是 JDK8 的应用,可以使用 Instant 代替 Date, LocalDateTime 代替 Calendar,DateTimeFormatter 代替 SimpleDateFormat。 JDK8日期详解

并发处理

【强制】高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁; 能锁区块,就不要锁整个方法体; 能用对象锁,就不要用类锁。

【强制】多线程并行处理定时任务时, Timer 运行多个 TimeTask 时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行,使用 ScheduledExecutorService 则没有这个问题。

【推荐】避免 Random 实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed 导致的性能下降。

说明: Random 实例包括 java.util.Random 的实例或者 Math.random()的方式。

正例: 在 JDK7 之后,可以直接使用 API ThreadLocalRandom, 而在 JDK7 之前, 需要编码保证每个线程持有一个实例。

【参考】 ThreadLocal 无法解决共享对象的更新问题, ThreadLocal 对象建议使用 static 修饰。这个变量是针对一个线程内所有操作共享的,所以设置为静态变量,

所有此类实例共享此静态变量 ,也就是说在类第一次被使用时装载,只分配一块存储空间,所有此类的对象(只要是这个线程内定义的)都可以操控这个变量。

【强制】在高并发场景中,避免使用”等于”判断作为中断或退出的条件。

说明: 如果并发控制没有处理好,容易产生等值判断被“击穿”的情况,使用大于或小于的区间判断条件来代替。

反例: 判断剩余奖品数量等于 0 时,终止发放奖品,但因为并发处理错误导致奖品数量瞬间变成了负数, 这样的话,活动无法终止。

【参考】 volatile 解决多线程内存不可见问题。对于一写多读,是可以解决变量同步问题,但是如果多写,同样无法解决线程安全问题。如果是 count++操作,使用如下类实现:

AtomicInteger count = new AtomicInteger();

count.addAndGet(1);

如果是 JDK8,推荐使用 LongAdder 对象,比 AtomicLong 性能更好(减少乐观锁的重试次数) 。

异常日志处理

【强制】 finally 块必须对资源对象、流对象进行关闭,有异常也要做 try-catch。

说明: 如果 JDK7 及以上,可以使用 try-with-resources 方式。

【推荐】方法的返回值可以为 null,不强制返回空集合,或者空对象等,必须添加注释充分说明什么情况下会返回 null 值。

【推荐】防止 NPE,是程序员的基本修养,注意 NPE 产生的场景:

1)返回类型为基本数据类型, return 包装数据类型的对象时,自动拆箱有可能产生 NPE。

反例: public int f() { return Integer 对象}, 如果为 null,自动解箱抛 NPE。

2) 数据库的查询结果可能为 null。

3) 集合即使 isNotEmpty,取出的数据元素也可能为 null。

4) 远程调用返回对象时,一律要求进行空指针判断,防止 NPE。

5) 对于 Session 中获取的数据, 建议 NPE 检查,避免空指针。

6) 级联调用 obj.getA().getB().getC(); 一连串调用,易产生 NPE。

正例: 使用 JDK8 的 Optional 类来防止 NPE 问题。

日志规范

【强制】应用中不可直接使用日志系统(Log4j、 Logback) 中的 API,而应依赖使用日志框架SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

private static final Logger logger = LoggerFactory.getLogger(Abc.class);

【强制】日志文件推荐至少保存 15 天,因为有些异常具备以“周”为频次发生的特点。

【强制】应用中的扩展日志(如打点、临时监控、访问日志等) 命名方式:appName_logType_logName.log。logType:日志类型,推荐分类有 stats/monitor/visit 等;logName:日志描述。这种命名的好处:通过文件名就可知道日志文件属于什么应用,什么类型,什么目的,也有利于归类查找。

正例: mppserver 应用中单独监控时区转换异常,如:

mppserver_monitor_timeZoneConvert.log

说明: 推荐对日志进行分类, 如将错误日志和业务日志分开存放,便于开发人员查看,也便于通过日志对系统进行及时监控。

【强制】对 trace/debug/info 级别的日志输出,必须使用条件输出形式或者使用占位符的方式。

说明: logger.debug("Processing trade with id: " + id + " and symbol: " + symbol);

如果日志级别是 warn,上述日志不会打印,但是会执行字符串拼接操作,如果 symbol 是对象,会执行 toString()方法,浪费了系统资源,执行了上述操作,最终日志却没有打印。

正例: (条件)

if (logger.isDebugEnabled()) {

logger.debug("Processing trade with id: " + id + " and symbol: " + symbol);

}

正例: (占位符)

logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);

【强制】避免重复打印日志,浪费磁盘空间,务必在 log4j.xml 中设置 additivity=false。

正例:

【强制】异常信息应该包括两类信息:案发现场信息和异常堆栈信息。如果不处理,那么通过关键字 throws 往上抛出。

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

【推荐】谨慎地记录日志。生产环境禁止输出 debug 日志; 有选择地输出 info 日志; 如果使用 warn 来记录刚上线时的业务行为信息,一定要注意日志输出量的问题,避免把服务器磁盘撑爆,并记得及时删除这些观察日志。

说明: 大量地输出无效日志,不利于系统性能提升,也不利于快速定位错误点。 记录日志时请思考:这些日志真的有人看吗?看到这条日志你能做什么?能不能给问题排查带来好处?

【推荐】可以使用 warn 日志级别来记录用户输入参数错误的情况,避免用户投诉时,无所适从。如非必要,请不要在此场景打出 error 级别,避免频繁报警。

说明: 注意日志输出的级别, error 级别只记录系统逻辑出错、异常或者重要的错误信息。

【强制】日志级别对应的关系

trace 用来跟踪线上问题,问题解决后删除

Warning 用来警告不符合业务规范等相关日志

Info 用来输出业务日志,用于排查和恢复数据

Error 只记录线上异常日志,方便监控报警

单元测试

单元测试中不准使用 System.out 来进行人肉验证,必须使用 assert 来验证

单元测试用例之间决不能互相调用,也不能依赖执行的先后次序

编写测试代码遵守 BCDE 原则

B:Border,边界值测试,包括循环边界、特殊取值、特殊时间点、数据顺序等

C:Correct,正确的输入,得到预期的结果

D:Design,与设计文档相结合,来编写单元测试

E:Error,强制错误信息输入(如:非法数据、异常流程、非业务允许输入等),并得到预期的结果

对于不可测的代码,建议做必要的重构,使代码变得可测,避免为了达到测试要求而书写不规范的代码

最后

以上就是明亮翅膀为你收集整理的java编码规范判断题_Java编码规范(个人总结向)的全部内容,希望文章能够帮你解决java编码规范判断题_Java编码规范(个人总结向)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部