时隔一年多,再次开始更新博客,各位粉丝们久等了。大家是不是以为我像大多数开发者一样三分钟热度,坚持了一年半载就放弃了,其实不是。在过去的一年时间我学习了《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.[强制] 代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束.(代码规范,易读) 反例: name / __name / $Object / n ...
- 阿里java开发手册中命名规约解读之DO/BO/DTO/VO/AO
前言 在阅读<阿里巴巴Java开发手册>时,看到命名规则中有这样一条 虽然知道这些是根据Java对象的角色所分配名称的后缀,但是没有弄清楚分别是什么意思,日常开发中也没有使用到. 网上查找 ...
- 阿里巴巴Java开发手册(格式规约篇)——查自己的漏-补自己的缺
(三) 格式规约 1. [强制]大括号的使用约定.如果是大括号内为空,则简洁地写成{}即可,不需要换行:如果是非空代码块则: 1) 左大括号前不换行.行. 2) 左大括号后换行. 3) 右大括号前换行 ...
- Java开发手册之数据库规约
1.不要使用 count(列名)或 count(常量)来替代 count(*),count(*)是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关. 2.cou ...
- 阿里巴巴 Java 开发手册 (八) 注释规约
1. [强制]类.类属性.类方法的注释必须使用 Javadoc 规范,使用/**内容*/格式,不得使用 //xxx 方式. 说明:在 IDE 编辑窗口中,Javadoc 方式会提示相关注释,生成 Ja ...
- Java开发手册之安全规约
1.用户敏感数据禁止直接展示,必须对展示数据进行脱敏.例如手机号.银行卡号等,中间要用*隐藏. 2.发贴.评论.发送即时消息等用户生成内容的场景必须实现防刷.文本内容违禁词过滤等风控策略,一般是用验证 ...
- 读阿里巴巴Java开发手册v1.2.0之编程规约有感【架构篇】
不为过去蹉跎,改变当下. 为什么开篇就送这么一句话给大家,我相信很多处于1-3年码龄的哥们儿们,在平时的编码历程中编码的个性可能是多彩的,每个人都有每个人特定的风格,但是我们现在这么随意写,以后这么 ...
- 《阿里巴巴Java开发手册v1.2》解析(编程规约篇)
之前在乐视天天研究各种底层高大上的东西,因为我就一个人,想怎么弄怎么弄.如今来了新美大,好好研读一下<阿里巴巴Java开发手册v1.2>.还要对这么看似简单的东西解析一番.毕竟现在带团队, ...
- Java开发手册-编程规约精选
# Java开发手册-编程规约精选 ## 总约 - 采用驼峰写法 ## 变量 - 首字母小写 ## 方法 - 方法名首字母小写- 参数首字母小写 ## 引用 - <阿里巴巴Java开发手册> ...
随机推荐
- ftp之filezilla使用记录
1.550 can't access file错误 我们在客户端查看文件时,有些文件被另外的程序占用了,就会出现这个错误.比如,log日志文件.解决办法:在server端,找到settings设置,找 ...
- Springboot mini - Solon详解(五)- Solon扩展机制之Solon Plugin
Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...
- C++异常之五 异常和继承
异常和继承 异常也是类,我们可以创建自己的异常类,在异常中可以使用(虚函数,派生,引用传递和数据成员等), 下面用一个自制的数组容器Vector,在对Vector初始化时来对Vector的元素个数进行 ...
- Unity 黑暗之光 笔记 第一章
第一章 设计游戏开始进入场景 1.设置相机视野同步 选中要调整的相机 GameObject - Align With View(快捷键 Ctrl + Shift + F)
- SpringBoot-2.3镜像方案为什么要做多个layer
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Hadoop核心-HDFS
上一篇我们熟悉了hadoop,本篇讲解一下hadoop第一个核心HDFS. 一.概述 HDFS是一个分布式文件存储系统,以流式数据访问模式存储超大文件,将数据分块存储到一个商业硬件集群内的不同机器上, ...
- Getting unknown property: common\models\Teacher::auth_Key
找了一个半小时,不知道为什么会缺少这个属性,数据库里面的字段明明都是有的. 然后随后找到了原因,是因为key中的k大写了,所以无法识别这个属性.把自己坑到了,以此为戒,以后多注意细节问题
- Java并发包之 CopyOnWriteArrayList
大家在学习Java的过程中,或者工作中,始终都绕不开集合.在单线程环境下,ArrayList就可以满足要求.多线程时,我们可以使用CopyOnWriteArrayList来保证数据安全.下面我们一起来 ...
- Tensorflow Windows安装
操作系统: Windows 7 安装步骤 Step 1: 安装Tensorflow支持的Python版本,配置环境变量 目前,Tensorflow支持: Python 3.5.x 64-bit fro ...
- MVC中使用AutoMapper
参考博文 https://www.cnblogs.com/fred-bao/p/5700776.html 前言 通常在一个应用程序中,我们开发人员会在两个不同的类型对象之间传输数据, 通常我们会用DT ...