时隔一年多,再次开始更新博客,各位粉丝们久等了。大家是不是以为我像大多数开发者一样三分钟热度,坚持了一年半载就放弃了,其实不是。在过去的一年时间我学习了《Java编程思想》这本书,因为都是写基础性的东西,所以没必要在博客上写出来。现在终于把700多页的编程思想看完了,回归博客,开始整理一波Java开发手册。

1.类名使用 UpperCamelCase 风格,但以下情形例外:DO / BO / DTO / VO / AO /PO / UID 等

2.方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格。

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

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

5.类型与中括号紧挨相连来表示数组。

6.POJO 类中的任何布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列化错误。比如,一个属性的名字定义为 boolean isChinese(是否中国人),框架为其生成的get方法名字你觉得是什么?是isChinese(),而不是isIsChinese(),这样就导致,在某些框架反射解析的时候,遇到isChinese()方法,他会觉得,有一个变量叫做chinese,而isChinese()是该变量对应的get方法。

7.避免在子父类的成员变量之间、或者不同代码块的局部变量之间采用完全相同的命名,使可读性降低。这样写,Java是支持的,因为子类继承后的覆盖嘛,还有变量的生命周期以最近的代码块为准。但是这样写,在项目中,别人看你的代码,很容易看的晕头转向。

8.在 long 或者 Long 赋值时,数值后使用大写的 L,不能是小写的 l,小写容易跟数字混淆,造成误解。其实不用L作为后缀也默认是long型数据,不过为了规范还是要标明。

9.不要使用一个常量类维护所有常量,要按常量功能进行归类,分开维护。

10.如果是大括号内为空,则简洁地写成{}即可,大括号中间无需换行和空格;

11.避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。

12.接口过时必须加@Deprecated 注解,并清晰地说明采用的新接口或者新服务是什么。
13.推荐使用java.util.Objects类中的equals(JDK7 引入的工具类)来判断两个对象是否相等。
14.对于Integer类型的数据比较是否相等。结论:在-128到127之间直接用==进行比较,结果正确,超出此范围,则结果不正确(int 无此限制)。原因:首先我们应该好奇的是,为什么超出范围之后比较结果就不正确还是为什么在范围内的比较结果正确?其实,Integer是一个类,哪怕他是基本数据类型对应的封装类,那他也是一个类,一个类的两个对象用==进行比较,实际上比较的不是他的值,而是他的内存地址。Integer a = 128,Integer b =128,你用a==b,不是比较128和128之间是否相等,而是比较a对象和b对象是否相等,实际是比较a对象的地址和b对象的地址是否相等,打印出来就是@123那一串的比较。所以结果肯定是错的。那为什么在-128到127之间的Integer对象比较结果又正确呢?这里涉及到Integer类的缓存机制。为了提高效率,对Integer对象进行赋值的时候,假如值在范围之外,Java是new了一个Integer对象,并将值放进去,这是一个全新的对象,所以在范围之外的Integer对象用==比较都是比较两个新new的Integer对象的地址。而对于在范围之内的Integer对象,比如Integer a=1,Java并没有new一个Integer对象,Java对-128到127之内的所有值都自动全部在加载的时候就已经生成了其对应的Integer对象,当你在代码中使用Integer a =1的时候,实际上是取出在缓存中值为1的那个Integer对象拿来用。所以Integer a=1,和Integer b =1,并不是新new了两个Integer对象,各自赋值为1,而是都用的是同一个已经在缓存中的Integer对象,所以对于这两个对象的比较,其实是同一个对象的比较,因此结果是true
15.对于浮点数的比较要特别注意。基本数据类型float,不能用==比较,封装类型Float不能用equals比较。原因:float,浮点,顾名思义浮点数采用“尾数+阶码”的编码方式,类似于科学计数法的“有效数字+指数”的表示方式。二进制无法精确表示大部分的十进制小数,所以对于浮点数的比较,要设置一个允许的范围,只要在范围内,就可以算作相等。完全相等是不太可能的。或者将浮点数转换为bigdecimal类型,然后再做运算与比较。
16.禁止使用构造方法 BigDecimal(double)的方式把 double 值转化为 BigDecimal 对象。BigDecimal(double)存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常。优先推荐入参为 String 的构造方法,或使用 BigDecimal 的 valueOf 方法,此方法内部其实执行了Double 的 toString,而 Double 的 toString 按 double 的实际能表达的精度对尾数进行了截断。
17.所有的 POJO 类属性必须使用包装数据类型。RPC 方法的返回值和参数必须使用包装数据类型。原因:基本数据类型会有默认值,而封装类不会。在某些业务场景中,值为null代表了一些含义(比如程序返回异常,存储异常等),假如使用基本数据类型,则自动赋值为默认值,这样使用者不知道该值是真的实际生产中的值,还是由于实际数据没查出来,而默认的值。而使用封装类就不会出现这种情况。还有,对于数据库中查出来的值是可能出现null的,对null值进行自动拆箱转换为基本数据类型时会报空指针异常。
18.深坑:“a,b,c,,,”.split(","),你们觉得这个split的结果数组的length是多少?我一直以为,数组长度是逗号个数加一,实际上!数组长度只有3!也就是说,如果你的字符串末尾有一段是空的,即便有逗号作为分隔符,最后的数组是直接给忽略了的。
19.对于字符串拼接的坑。相信大家看过面试题的都知道字符串拼接的坑。但是大家了解的可能不是很详细。咱们一步一步分析一下字符串拼接的问题。String s = "aaa",s=s+"nnn"。相比于StringBuiler的append方法,为什么大家都说直接用+对string对象进行拼接效率不高呢?可能有人会说,在使用+拼接字符串的时候,编译器会不断地new新的string对象,然后抛弃旧的string对象,最后完成拼接,所以效率慢。这样说是错的!可能在Java的历史中曾经这样处理过,但是在1.5的时候编译器早都不这样处理了,可能更早。编译器会自动将string对象转换为stringbuilder对象,然后调用append方法,最后调用tostring方法返回。那么到这里有人问了,那为什么有人说用+号拼接字符串效率低呢?编译器已经自动为我们做优化了啊!其实,确实编译器自动优化了。但是在某一个特殊情况下,编译器优化的不够彻底。比如一个字符串在循环体中进行拼接。编译器实际做法是,每一次循环都会生成一个Stringbuilder对象,然后调用append方法拼接,在循环结束的时候,回收该stringbuilder对象,在下一次循环开始的时候,重新生成另一个StringBuilder对象,这样就造成了资源浪费。
20.获取当前时间的毫秒数,你会怎么办?有同学说,简单!new Date().getTime(),呵呵,这样做倒是可以,但是还有更简便的方法System.currentTimeMillis();这样不仅写法简单,而且不用生成新的对象,直接使用的 时System对象。
21.在使用 java.util.stream.Collectors 类的 toMap()方法转为 Map 集合时,一定要使用含有参数类型为 BinaryOperator,参数名为 mergeFunction 的方法,否则当出现相同 key值时会抛出 IllegalStateException 异常。

22.在使用 java.util.stream.Collectors 类的 toMap()方法转为 Map 集合时,一定要注意当 value 为 null 时会抛 NPE 异常。
23.ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException 异常。说明:subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList 而是 ArrayList 的一个视图,对于 SubList 子列表的所有操作最终会反映到原列表上。
24.Collections 类返回的对象,如:emptyList()/singletonList()等都是 immutable list,不可对其进行添加或者删除元素的操作。
25.在 subList 场景中,高度注意对父集合元素的增加或删除,均会导致子列表的遍历、增加、删除产生 ConcurrentModificationException 异常。这是因为subList所产生的是在原List的基础上的视图,当原list改变之后视图就可以说是报废了。
26.使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一致、长度为 0 的空数组。说明:如果使用另一个不带参数的toArray,其返回值为Object数组,因为你没给人家参数,人家也不知道类型,只能生成Object数组。而数组臭名昭著的一点就是不能进行强转。具体原因就不说了,算了还是提一嘴吧。类型转换,分为父类型转换为子类型,或者子类型转换为父类型。子类型对象可以直接赋值给父类型,因为子类就是父类的特殊情况,比如男人(子类)是人(父类)。但是当父类引用(指向父类的对象的引用)转换为子类引用的时候,就需要强制转换。能不能转换成功,需要看这个引用指向的真正底层对象是父类的还是子类的。如果真正指向的是子类的,那么转换就可以成功。而不带参数的toArray其底层直接就是new的一个Object数组,想要将其强转为子类型当然是行不通的。单数如果底层实际是一个子类型(比如String)类型的数组,只不过方法返回的时候当作Object数组返回,这个时候再强转为String数组,是可以成功的。
27.线程池不允许使用Executors创建,要使用ThreadPoolExecutor创建,因为前者在创建线程池的过程中有如下弊端:或允许的请求队列过长,或允许创建的线程数量过多。
28.SimpleDateFormat类是线程不安全的类,使用时需要加锁。
29.多线程处理定时任务时Timer运行多个TimerTask时,只要其中一个task抛出异常,其他所有的task都会停止运行,ScheduledExecutorService则不会有这个问题。
30.在高并发的场景中,避免使用==0作为判断逻辑终止的条件,因为如果并发处理不当,可能会直接从1跳过判断条件直接到-1。
31.三目运算符一定要注意空指针异常的问题。说明:在三目运算符中if(true)?a:b;如果a和b有一个时基本数据类型,一个是封装类,则会先将封装类拆箱为基本数据类型再计算。假如一个是范围较小的Integer一个是范围较大的Float,会执行拆箱操作,将Integer转换为int再升级为float再计算,所以在拆箱过程中容易出现空指针异常。
32.获取随机数的两种方法。第一种Math.random()注意该方法返回的是double类型的数据,范围是0(包含)到1(不包含),所以处理的时候要注意,可能出现为0 的结果。第二种就是正经的随机数类Random,方法多,好用。如果要取随机整数,直接用Random类就好,不要使用Math类生成double再去乘以10或100.

Java开发手册之编程规约的更多相关文章

  1. Java 开发手册之编程规约

    一.编程规约 (一) 命名规约 1.[强制] 代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束.(代码规范,易读) 反例: name / __name / $Object / n ...

  2. 阿里java开发手册中命名规约解读之DO/BO/DTO/VO/AO

    前言 在阅读<阿里巴巴Java开发手册>时,看到命名规则中有这样一条 虽然知道这些是根据Java对象的角色所分配名称的后缀,但是没有弄清楚分别是什么意思,日常开发中也没有使用到. 网上查找 ...

  3. 阿里巴巴Java开发手册(格式规约篇)——查自己的漏-补自己的缺

    (三) 格式规约 1. [强制]大括号的使用约定.如果是大括号内为空,则简洁地写成{}即可,不需要换行:如果是非空代码块则: 1) 左大括号前不换行.行. 2) 左大括号后换行. 3) 右大括号前换行 ...

  4. Java开发手册之数据库规约

    1.不要使用 count(列名)或 count(常量)来替代 count(*),count(*)是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关. 2.cou ...

  5. 阿里巴巴 Java 开发手册 (八) 注释规约

    1. [强制]类.类属性.类方法的注释必须使用 Javadoc 规范,使用/**内容*/格式,不得使用 //xxx 方式. 说明:在 IDE 编辑窗口中,Javadoc 方式会提示相关注释,生成 Ja ...

  6. Java开发手册之安全规约

    1.用户敏感数据禁止直接展示,必须对展示数据进行脱敏.例如手机号.银行卡号等,中间要用*隐藏. 2.发贴.评论.发送即时消息等用户生成内容的场景必须实现防刷.文本内容违禁词过滤等风控策略,一般是用验证 ...

  7. 读阿里巴巴Java开发手册v1.2.0之编程规约有感【架构篇】

     不为过去蹉跎,改变当下. 为什么开篇就送这么一句话给大家,我相信很多处于1-3年码龄的哥们儿们,在平时的编码历程中编码的个性可能是多彩的,每个人都有每个人特定的风格,但是我们现在这么随意写,以后这么 ...

  8. 《阿里巴巴Java开发手册v1.2》解析(编程规约篇)

    之前在乐视天天研究各种底层高大上的东西,因为我就一个人,想怎么弄怎么弄.如今来了新美大,好好研读一下<阿里巴巴Java开发手册v1.2>.还要对这么看似简单的东西解析一番.毕竟现在带团队, ...

  9. Java开发手册-编程规约精选

    # Java开发手册-编程规约精选 ## 总约 - 采用驼峰写法 ## 变量 - 首字母小写 ## 方法 - 方法名首字母小写- 参数首字母小写 ## 引用 - <阿里巴巴Java开发手册> ...

随机推荐

  1. springboot中使用h2数据库(内存模式)

    使用H2的优点,不需要装有服务端和客户端,在项目中包含一个jar即可,加上初始化的SQL就可以使用数据库了 在springboot中引入,我的版本是2.1.4,里面就包含有h2的版本控制 <!- ...

  2. Java JVM——2.类加载器子系统

    概述 类加载器子系统在Java JVM中的位置 类加载器子系统的具体实现 类加载器子系统的作用 ① 负责从文件系统或者网络中加载.class文件,Class 文件在文件开头有特定的文件标识. ② Cl ...

  3. Erlang那些事儿第2回之我是模块(module),一文件一模块

    前几篇文章会写得比较基础,但是既然要写一系列的文章,还是得从基础开始写.我刚学Erlang碰到最大的问题是,想网上搜索下语法,结果却是寥寥无几,而且介绍得不是很系统,对我了解一些细节是有影响的,正好我 ...

  4. Python 中日期函数

    导入日期库 datetime import datetime # 或者from datetime import datetime ,date 字符串转datetime

  5. python解压可迭代对象赋值给多个变量

    如果一个可迭代对象的元素个数超过了变量的个数,会出现"解压值太多"的异常,python提供*号表达式(码夫破石的理解)来解决. 1,求一组平均值,就以类似学生成绩为例,要求是去掉第 ...

  6. html嵌入腾讯视频的方法

    1.首先我们从腾讯视频网站上找到一个视频网页的连接,格式是这样的 https://v.qq.com/x/page/b0136et5ztz.html 上面我标红色的是视频的vid 2.我们把vid放到接 ...

  7. 面试官让你讲讲Linux内核的竞争与并发,你该如何回答?

    @ 目录 内核中的并发和竞争简介 原子操作 原子操作简介 整型原子操作函数 位原子操作函数 原子操作例程 自旋锁 自旋锁简介 自旋锁操作函数 自旋锁例程 读写自旋锁 读写锁例程 顺序锁 顺序锁操作函数 ...

  8. SpringBoot整合任务调度框架Quartz及持久化配置

    目录 本篇要点 SpringBoot与Quartz单机版快速整合 引入依赖 创建Job 调度器Scheduler绑定 自动配置,这里演示SimpleScheduleBuilder 手动配置,这里演示C ...

  9. 3. Longest Substring Without Repeating Characters寻找不重复的最大子串

    首先弄清楚Substring和Subsequence,前者是子串,要求连续,后者是子序列,可以不连续 public int lengthOfLongestSubstring(String s) { / ...

  10. Above the Median

    http://www.forioi.com/p/3212 农夫约翰把他的N(1<=N<=1e5)奶牛排在一排来衡量他们的高度,牛i有:高度H_I(1<=H_I<=1e9)纳米– ...