Java 高质量编程建议(笔记3)
来源:互联网 发布:雅思口语书 知乎 编辑:程序博客网 时间:2024/06/03 15:58
Ad-18:避免instanceOf非预期结果
1)instanceOf是一个简单的二元操作符,用来判断一个对象实例是否属于某个类;
2)直接常量的类型是基本类型,而不是其包装类型, 如果右操作数是包装类型,则编译失败,反之亦然;
3)instancOf的左操作数如果是null,直接返回false,不关心运算的右操作数是什么类型;
4)如果对象的类型是是右操作数的子类,则返回成功;
5)如果左操作数的类型与右操作数的类型不存在父子关系(类型关系树),编译会失败;
6)右操作数是基本类型(八大基本类型)一定编译不过;
7)泛型在编译成字节码时,T为Object类型,因此右操作数只要不是基本类型,都能编译通过;
Ad-19:断言绝对不是鸡肋
1)在防御性编程中经常用断言(Assertion)对参数和环境作出判断;
2)断言使用方法:
assert <布尔表达式>
assert <布尔表达式>:<错误信息>
3)布尔表达式如果为假,抛出AssertionError错误,并附带了错误信息;
4)assert默认不启用;
5)assert抛出的异常AssertionError是继承Error的;
6)assert不能用于以下场景:
a)对外公才的方法;
b)在执行的逻辑代码中;
7)assert使用的三种场景:
a)在私有方法中使用assert对输入参数做判断;
b)流程控制中不可能到达的区域;
c)建立程序探针,例如:函数的两个变量之间的逻辑关系满足某个表达要求,不满足的话,就有异常;
Ad-20:不要只替换一个类
1)一个类中定义的常量(对于final修饰的基本类型和String类型), 编译器会认为是稳定态的(immutable status),所以编译的时候就直接把值编译到字节码中,避免运行期间引用,提升代码执行效率;
2)对于final修饰的非基本类型, 编译器认为它不是稳定态的,在编译的时候建立引用关系;
3)对于上述两点, 如果是稳定态的,如果只替换了定义常量的类,那么新的常量不会影响到程序,但是如果不是稳定态的,则新的常量;
Ad-21:用偶判断,不用奇判断
(i % 2 == 1)? "奇数":"偶数"
Java中取模的计算方法:
public static int remainder(int divided, int divisor)
{
return divided - divided / divisor * divisor;
}
因此当 i = -1时,i%2= -1;所以判断是否是偶数,最好是用 i % 2 == 0
Ad-22:使用整数类型处理货币
1)大多数语言中,都支持两种浮点数,分别是float类型(俗称:单精度)和double类型(俗称:双精度),其长度分别是4字节和8字节;
2)浮点数在计算机中存储都支持IEEE标准,float类型按照IEEE的RS32.24, double类型按照IEEE的RS64.53;
3)浮点数(注意这里是将浮点数转换成2进制科学计数表示)在计算机中存储分三部分:
a)符号位(Sign):0表示正数,1表示负数;
b)指数位(Exponent):用于存储科学计数法中的指数数据,采用移位存储;
c)尾数位(Mantissa):科学计数法中的基数部分(尾数部分,即小数点后面,因为小数点前面一定是1,没有必要再保存);
5)在计算机中,只有0.5的N次方可以准确的表达(前提是精确度有足够的位数)
例如:0.4 的二进制表示 0.0110, 其中0110循环,无限循环下去;
6)float类型浮点数占用32Bits,其中符号位S占1Bit,指数位E占8Bits,尾数位占23Bits,其Bit位分布见图;
double类型浮点数占用64Bits,其中符号位S占1Bit,指数位E占11Bits,尾数位占52Bits,其Bit位分布见图;
关于浮点数,可以参考网上其他文章,下面这篇文章写得很详细;
http://bbs.chinaunix.net/thread-3746530-1-1.html
http://blog.csdn.net/masefee/article/details/5272554
7)在Java中不宜使用浮点数表示货币类型,通常银行或者金融业表示需要表示小数点后(10进制)4位,然后输出的时候经过四舍五入法精确两位(RMB到“分”);
8)但是由于浮点数的精度问题,通常采用两种方式解决,Java 的BigDicimal或使用整型;
Ad-23:不要让类型默默转换
Java的表达式先计算,然后再转换类型,即如果表达是的类型是范围小于赋值的变量类型表示的范围,则表达式先计算,然后再转换类型。
例如:
int speed = 30 * 1000 * 1000;
long dist = speed * 60 * 8;
计算的结果将出现溢出,原因是speed * 60 * 8 表达式的类型是int类型,计算会溢出,计算完之后,才转换类型;
修改:
long dist = 1L * speed * 60 * 8;
Ad-24:边界值,防止判断边界值时溢出
在边界值判断中,经常使用 表达式 与 阈值的大小进行判断。但是表达式可能出现溢出,导致条件表达式判断还是OK的。
例如:
一个会员最多拥护2000个优惠商品;某会员当前有800个优惠商品;如果程序判断cur + input < LIMIT;
如果input出现错误,2147483647,那么将出现异常,但是条件表达式还是返回true的。
Ad-25:不要让四舍五入亏了一方
1)四舍五入在金融和商业运行中经常使用到,但是四舍五入并不是绝对的公平,原因:1~4被舍掉,而5~9则进入,明显入多,舍少;
2)Java之前,通常使用Math.round来获取制定精度的数值;
3)银行家舍入法:
3.1)舍去的位小于5时,则直接舍去;
3.2)舍去的位大于6时,则直接进位;
3.3)舍去的位为5时,首先舍去位后面位的数值,如果非0,则进位; 如果舍去位后面位的数值为0,则看舍去位前面,如果为偶数,则舍去,如果为奇数则进位;
4)在金融和商业软件中,经常使用BigDecimal的setScale方法和RoundingMode来处理各种舍入和进位;
5)RoundingMode支持7种进位和舍去方法:
5.1)ROUND_UP: 向远离0方向舍入, 向绝对值最大的方向舍入,只要舍弃位非0即进位;
5.2)ROUND_DOWN: 向靠近0方向舍入, 向绝对值最小的方向舍入,注意:所有的位都舍弃,不存在进位;
5.3)ROUND_CEILING:向正无穷方向舍入,与Math.round相同;
5.4)ROUND_FLOOR:向负无穷方向舍入;
5.5)HALF_UP: 传统的四舍五入;
5.6)HALF_DOWN:准确来说是五舍六入;
5.7)HALF_EVEN:银行家舍入法;
- Java 高质量编程建议(笔记3)
- Java 高质量编程建议(笔记1)
- Java 高质量编程建议(笔记2)
- Java 高质量编程建议(笔记4)
- Java 高质量编程建议(笔记5)
- Java 高质量编程建议(笔记6)
- Java 高质量编程建议(笔记7)
- Java 高质量编程建议(笔记8)
- 高质量编程笔记
- 高质量java编程
- 《高质量C/C++编程》学习笔记3(内存)
- C++高质量编程学习笔记(3)
- 高质量编程的11条建议
- 编写高质量Java代码的建议
- 编写高质量JAVA程序代码的建议
- 编写高质量JAVA程序代码的建议
- 高质量C++编程笔记
- 高质量编程指南笔记
- 一个任务拥有多个外向转移jbpm.api.JbpmException: No transition named 'to 总经理审批' was found.
- 等待
- 我们今年二十一二岁
- What's wrong with arrays?
- linux硬盘格式化和创建swap分区
- Java 高质量编程建议(笔记3)
- linux tar命令
- cocos2d 随机数设计
- 读《轻松SCRUM之旅》有感第三篇
- HID Descriptor
- Java内存管理白皮书
- ubuntu环境下内核编译
- response.setContentType和response.setCharacterEncoding区别
- Silverlight + RIA Service的SUID的实例