java开发编码规范

  1. 方法的返回类型, 方法参数, 变量声明时均采用接口类型, 而不是实际类型:
/** 定义接口变量为接受类型的好处: 1).面向接口编程 一种规范约束 制定者(或者叫协调者),实现者(或者叫生产者),调用者(或者叫消费者)。 接口本质上就是由制定者来协调实现者和调用者之间的关系。 只有实现者和调用者都遵循“面向接口编程”这个准则,制定者的协调目的才能达到。 接口的语义是can-do语义,表约束(Constraint)像JDBC的规范API,无论你使用哪一套实现,咱们使用的时候都是使用相同的API. 分离设计与实现 使得系统能够支持开闭原则和依赖倒转原则。设计师能够设计出接口,而程序员能够依照接口去写实现。 2).解耦合 在必定程度上解耦合,依赖接口还不依赖具体实现,在替换实现类的时候,能够将影响减到最小. 3).在依赖接口的状况下,单元测试更容易,使用mock也更容易,在TDD中,测试驱动就是要让程序易于测试。 4).与设计有关 在一个面向对象的系统中,系统的各类功能是由许许多多的不一样对象协做完成的。 在这种状况下,各个对象内部是如何实现本身的对系统设计人员来说就不那么重要了; 而各个对象之间的协做关系则成为系统设计的关键。 在OSGI规范中,接口与实现的分离是用得最淋漓尽致的。 5).参考spring中的IOC的实现 */ public Map<String, Object> getStockWarrantIV(String ul, String updateDate) { //HashMap<String, Object> ivMap = new HashMap<>(); Map<String, Object> ivMap = new HashMap<>(); try { String key = STOCK_WARRANT_IV_PREFIX + ul; String hashKey = updateDate; ivMap = (HashMap<String, Object>) redisTemplate.boundHashOps(key).get(hashKey); } catch (Exception e) { LOG.error("getStockWarrantIV", e); } return ivMap; } 
  1. 代码中不要有多余的空行, 无效的注释,无心义的注释要删掉; 注释要规范, 符合javadoc原则;注释和日志细节写清楚,不要出错误;变量命名规范,不要存在歧义和冲突;java

  2. 方法命名符号常规英语表达习惯, 能从名字明白方法的做用;程序员

  3. 调用工具类, 尽可能调用已经封装好的工具类方法,减小自定义工具类方法编码;redis

  4. 判断字符串非空, 调用StringUtils类中方法, 注意isBlank和isEmpty的区别spring

1.StringUtils里的isEmpty方法和isBlank方法的区别 isEmpty() public static boolean isEmpty(String str) { return str == null || str.length() == 0; } isBlank() public static boolean isBlank(String str) { int strLen; if (str != null && (strLen = str.length()) != 0) { for(int i = 0; i < strLen; ++i) { // 判断字符是否为空格、制表符、tab if (!Character.isWhitespace(str.charAt(i))) { return false; } } return true; } else { return true; } } 结论 1).isEmpty 没有忽略空格参数,是以是否为空和是否存在为判断依据 2).isBlank 是在 isEmpty 的基础上进行了为空(字符串都为空格、制表符、tab 的状况)的判断。(通常更为经常使用) StringUtils.isEmpty("yyy") = false StringUtils.isEmpty("") = true StringUtils.isEmpty(" ") = false StringUtils.isBlank("yyy") = false StringUtils.isBlank("") = true StringUtils.isBlank(" ") = true 

6.处理时间用joda库中的函数和java8中的时间函数,保证线程安全,避免使用Calendar以及jdk8之前的方法;数据库

7.判断集合非空, CollectionUtils.isNotEmpty; 判断Map非空, MapUtils.isNotEmpty; 尽可能少用原始方法判断, 能用工具包尽可能用工具包;编程

8.集合排序, 天然逆序用Comparator.reverseOrder(), 不要用重写compare方法实现;缓存

9.new的对象不能能为null, 不作为null的判断, 而且不作无效的new操做, 有赋值就不new;安全

10.在设计到时间的格式转换时注意时区的影响, 以下:并发

//用format会致使时区的错误 hkStockRedisDao.setCallOrPullIVsRegion(ul, String.format("%tF", time.toDate()), ivMaps); //考虑时区的影响, 尤为是在设计到不一样交易所的状况 hkStockRedisDao.setCallOrPullIVsRegion(ul, TimeUtils.printHkDate(time.getMillis()), ivMaps); public static final DateTimeZone TIMEZONE_HK = DateTimeZone.forID("Asia/Hong_Kong"); private static final DateTimeFormatter COMMON_DATE_FORMAT_HK = DateTimeFormat.forPattern("yyyy-MM-dd") .withZone(TIMEZONE_HK); public static String printHkDate(long timestamp) { return COMMON_DATE_FORMAT_HK.print(timestamp); } 

11.在作条件判断时考虑周全,无效无心义的判断要减小,没有必要的else尽可能减小, return语句在if, else里尽可能减小, 在外面return;maven

12.在作时间的比较计算时, 用joda库或者java8中的日期操做方法: 好比判断时间相差三个月, 用DateTime中的minusMonths函数,考虑11月和2月之间的差

int timeDiff = expireDateTime.minusMonths(3).compareTo(currentDate); 
  1. 无效的import要及时去掉, StringUtils用lang3的;

  2. 操做数据库时须要考虑到性能因素, 不能只认结果;

  3. 异常处理, 强转须要捕获异常;

try 块:用于捕获异常。其后可接零个或多个catch块,若是没有catch块,则必须跟一个finally块。 catch 块:用于处理try捕获到的异常。 finally 块:不管是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回以前被执行。在如下4种特殊状况下,finally块不会被执行: 1)在finally语句块中发生了异常。 2)在前面的代码中用了System.exit()退出程序。 3)程序所在的线程死亡。 4)关闭CPU
  1. 类型相同的变量直接赋值, 无需在从新new

  2. 出现太多常量, 须要提取公共常量;

  3. 分页时主要默认最小页大小和最大页大小, 避免返回所有;

  4. 常量命名规范, 大写下划线;

  5. 方法权限, 类中调用private, 子类调用protected;

  6. 代码格式调整option+command+l, "{"前有空格, 语句对齐, 用option+command+l快捷键对齐;

  7. 若是用//注释, 须要与注释内容之间有一个空格;

  8. 相同业务类型, 相赞成义用才用可变参数, 可变参数放在最后一个参数;

  9. 包装类型的值比较用equals方法, 不用==, 由于java在包装类型有缓存;

  10. 构造方法里不加任何业务逻辑, 放在init方法里;

  11. 只要重写equals就必须重写hashCode

  12. 关于通配符: 泛型通配符<? extends T>来接收返回的数据,此写法的泛型集合不能使用add方 法,而<? super T>不能使用get方法,作为接口调用赋值时易出错;PECS(Producer Extends Consumer Super)原则:第1、频繁往外读取内 容的,适合用<? extends T>。第2、常常往里插入的,适合用<? super T>;

  13. 不要在 foreach 循环里进行元素的 remove/add 操做。remove 元素请使用 Iterator 方式,若是并发操做,须要对 Iterator 对象加锁。

  14. 集合初始化时,指定集合初始值大小

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

  16. 线程池不容许使用 Executors 去建立,而是经过 ThreadPoolExecutor 的方式,这样 的处理方式让写的同窗更加明确线程池的运行规则,规避资源耗尽的风险。

  17. 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 代替 SimpleDateFormat,官方给出的解释:simple beautiful strong immutable thread-safe
  1. public方法传参注意, 防止调用者调错

  2. if else 考虑清楚, 须要让看的人以为逻辑清晰

  3. 分页实现, 须要totalPage, pageSize, page三个参数, totalPage和page须要返回给客户端

  4. maven在打包发布前要clean下, 防止本地的target下的classess影响发布后的结果

  5. 字符串截图判断是否越界 stockStat.getNameCN().substring(2, 4);

比较: redisTemplate.boundValueOps(key).get() redisTemplate.opsForValue().get(key);

相关文章
相关标签/搜索