注意:浮点数表示的不是一个准确的数字
存储货币时,均以最小货币单位且整型类型来进行存储。
0.1 默认是double类型,有效位数均为53
0.1f 有效位数23
(double)e 会在flout类型上补0
浮点数据类型的问题:精度丢失
浮点数通过科学计数法表示,是二进制形式的科学计数法,所有底数为2
有效位数其实前面省略了一个1,共24位(有效数字保存的只有小数部分)
十进制科学计数法规格化:
整数部分:1-9
二进制科学计数法规格化:
保持小数点前有且只有一个“1”(省略了前面的1,有效数字保存的只有小数部分)
精确的小数存储——decimal,java中用java.math.BigDecimal类
浮点数据避坑:
1、浮点数之间的等值判断,基本数据类型不能用==,包装数据类型不能用equals来判断。
(应该指定一个误差范围,两个浮点数的差值在此范围内,则认为是相等的)
2、BigDecimal的等值比较应该用compareTo()方法(如果前面值小返回-1,相等返回0,大返回1),而不是equals方法。
equals():方法会比较值和精度(1.0 和 1.00返回false)
compareTo():会忽略精度
3、禁止使用构造方法BigDecimal(double)的方式把double值转化为BigDecimal对象
日期格式化注意
1、日期格式化时,传入pattern中表示年份统一使用小写y。
小写yyyy:表示当天所在的年
大写YYYY:表示week in which year(JDK7之后引入的概念)即当天所在的周属于的年份,一周从周日开始,周六结束,只要本周跨年,返回的YYYY就是下一年。
2、分清大小写的意义:
(1)表示月份是大写的M;
(2)表示分钟则是小写的m;
(3)24小时制的是大写的H;
(4)12小时制的则是小写的h。
建议:在util类中将pattern进行预设,并定义好相关的处理方法。
3、获取当前毫秒数:
(1)System.currentTimeMills(),而不是用new Date().getTime()。(占用空间,又走弯路耗时间,因为对象里面也是用的该方法)
(2)获取更加精确的纳秒级时间值,使用System.nanoTime的方式
(3)在JDK8中,推荐使用Instant类获取时间戳。
控制语句避坑规范switch
1、每个case要么通过continue/break/return等来终止
2、要么注释说明程序将继续执行到哪一个case为止
3、在一个switch块内,都必须包含一个default语句并且放在最后
(注意:走了default就一直走下去如果没有continue/break/return等来终止)
4、当switch括号内的变量类型为String并且此变量为外部参数时,必须先进行null判断
循环1、在if/else/for/while/do语句中必须使用大括号
2、表达异常的分支时,少用if-else方式
(嵌套超过3层,则代码有问题)
三目运算符
三目运算符高度注意类型对齐时,可能抛出因自动拆箱导致的NPE异常
condition?表达式1 :表达式2,
说明:以下两种场景会触发类型对齐的拆箱操作:
表达式1或表达式2的值只要有一个是原始类型。.
表达式1或表达式2的值的类型不一致,会强制拆箱升级成表示范围更大的那个类型。
控制语句
1、不要在其他表达式(尤其是条件表达式)中,插入赋值语句。
2、不要在条件判断中,执行其他复杂的语句,已提高可读性。
3、避免使用取反逻辑运算符。(instanceof必须取反逻辑)
高并发场景中控制语句规约在高并发场景中,避免使用”等于”判断作为中断或退出的条件
如果并发控制没有处理好,容易产生等值判断被“击穿”的情况,使用大于或小于的区间判断条件来代替
方法一先查询,执行的是快照操作,可能不是最新的,其他可以改变。
(可能超卖)
方法二先读,找这条记录,是当前读,对数据库增删改肯定加锁,加上id就对这条记录加行锁,并不锁表。事务结束之后,锁自动释放。
(肯定不超卖)
需要参数校验的场合1、调用频次低的方法。
2、执行时间开销很大的方法。此情形中,参数校验时间几乎可以忽略不计,但如果因为参数错误导致中间执行回退,或者错误,那得不偿失。
3、需要极高稳定性和可用性的方法。
4、对外提供的开放接口,不管是RPC/API/HTTP接口。
5、敏感权限入口。
6、公开接口需要进行入参保护,尤其是批量操作的接口。
不需要参数校验的场合1、极有可能被循环调用的方法
极有可能被循环调用的方法。但在方法说明里必须注明外部参数检查。
2、底层调用频度比较高的方法
底层调用频度比较高的方法。毕竟是像纯净水过滤的最后一道,参数错误不太可能到底层才会暴露问题。一般DAO层与Service层都在同一个应用中,部署在同一台服务器中,所以DAO的参数校验,可以省略。
3、被声明成private
被声明成private只会被自己代码所调用的方法,如果能够确定调用方法的代码传入参数已经做过检查或者肯定不会有问题,此时可以不校验参数。
面向对象编程(Object-Oriented Programming, 00P)三个主要目标:可维护性、可重用性和可扩展性。
面向对象四大特征
抽象:
对需求进行业务抽象和建模分析,通过模型的行为组合去共同解决某一类问题
封装:
封装是一种对象功能内聚的表现形式,使模块之间耦合度变低,更具有维护性
继承:
继承使子类能够继承父类,获得父类的部分属性和行为,使模块更有复用性
多态:
多态使模块在复用性基础上更加有扩展性,使系统运行更有想象空间
七大设计原则
共同点:提升软件的可扩展性,可维护性是抽象思维和归纳思维的集中体现
OOP规约-可变参数
1、相同参数类型,相同业务含义
2、避免使用Object
3、可变参数必须放置在参数列表的最后
4、尽量不用可变参数
方法重载,执行匹配度最高的方法
OOP规约-对象的比较1、所有整型包装类对象之间值的比较,全部使用equals方法比较
对于Integer var=?在-128至127之间的赋值,Integer 对象是在IntegerCache.cache产生,会复用已有对象,这个区间内的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,
推荐使用equals方法进行判断。
2、应使用常量或确定有值的对象来调用equals
0bject的equals方法容易抛空指针异常
推荐使用JDK7引入的工具类java.tilObjectstequals(Object a, Object b)
OOP规约-方法及属性1、所有的POJO类属性必须使用包装数据类型
(可以为null, 且基本数据类型有默认值)
2、定义DO/DTO/VO等POJO类时,不要设定任何属性默认值
(可能出现判断错误,不知道有该值)
3、定义数据对象DO类时,属性类型要与数据库字段类型相匹配
4、getter/setter方法中,不要增加业务逻辑
5、禁止在POJO类中,同时存在对应属性xXx的isXxx()和getXxx()方法。
6、构造方法里面禁止加入任何业务逻,,如果有初始化逻辑,请放在init方法中



