[Java解惑]读书笔记分享
这本书主要讲了Java中经常遇到的坑, 并给出了解释以及解决办法. 读完之后很有收获
- 读书笔记
- 表达式之谜
- 奇数性
用下面的表达式判断一个数是否是奇数
问题: 负数无法得出正确的结果. 例如当 i = -3
时, 上述结果是-1
.
可以修改为如下形式
更进一步的, 可以考虑把区域操作改为AND(&)
.
- 找0时刻
计算表达式
原因: 并非所有的小数都可以用二进制浮点数明确表示
请注意, 虽然表达式System.*out*.printf("%.2f", (2.00 - 1.10));
会显示出正确的结果, 但是这并不表示是对底层通用的解决方案.
因为二进制浮点数对于货币运算是非常不合适的.
一种方案是以分为单位, 另外一种是使用BigDecimal
.
一定要使用字符串构造参数BigDecima(String)
, 不要使用BigDecima(double)
.
- 长整除
两个long类型的数相除.
运行结果是5
MICROS_PER_DAY
溢出了. 虽然放在long
中是可以的, 但是放在int
中会溢出.
这个计算是按照int
来计算的, 只有在运算完之后, 才会被提升到long
, 而此时已经溢出了.
为什么会按照int
的方式计算? 因为所有的因子都是int
类型.
一种比较好的方式是把long
类型作为第一个因子.
修改后的程序如下
- 初级问题
计算表达式
为什么会这样呢?
5432l
中的l
, 表示该数字是long
类型. 因此建议写成大写.
- 十六进制的趣事
计算下面表达式
为什么不是1cafebabe
呢
要注意到, 十六进制不像十进制一样字面量都是正的, 如果想表示负数在前面加-
号就可以了.
因此, 该表达式左侧是一个long类型数字, 右侧是一个int
类型的数字, 且为负数. 为了执行该运算, 会将int
类型转化为long
类型. 提升之后的数字是0xffffffffcafebabe
.
修改方法如下. 即把两个数字都变成long
类型.
- 多重转型
观察下面表达式
其结果不是-1
, 而是65535
转化顺序是 int → byte → char → int
该程序的行为紧密依赖于转型的符号扩展行为. Java使用基于2的补码的二进制运算, 因此int类型的数值-1的所有32位都是置位的.
第一次从int → byte, 窄化转换, 仍是-1.
第二次byte → char, 拓展并窄化的转化. byte是有符号类型的, char是无符号类型的. 不能用char表示一个负的byte. 因此这个过程是byte → int → char.
可以将规则描述如下: 如果最初的数值类型是有符号的,那么就执行符号扩展。如果他是char那么不管他将要被转化成什么类型,都执行零扩展。
- 互换内容
一种可行的方式如下
这种方式不推荐使用.
Java的操作符操作是从左到右执行的.
给我们的经验就是不要对相同的变量赋值两次.
- Dos Equis
观察下面表达式
转化规则如下
最好在条件表达式中使用相同的类型.
- 半斤
不能简单的认为下面两个表达式是相等的
原因如下
可以观察下面的例子
因此, 不要将符合运算符用于byte, short, char类型. 避免符合类型的转型.
- 八两
但是, 上面的例子反过来, 也不能就认为高枕无忧了.
复合赋值操作符要求两个操作数都是原生类型的,例如int。或包装了的原生类型。例如integer. 但是有一个例外, 那就是如果操作符左侧的操作数是string类型的。那么他允许右侧的操作数是任意类型。
- 字符之谜
- 最后的笑声
- ABC
- 动物庄园
- 转义字符的溃败
- 令人晕头转向的Hello
- 行打印程序
- 嗯?
- 字符串奶酪
- 漂亮的火花
- 我的类是什么
- 我的类是什么? 镜头2
- URL的愚弄
- 不劳无获
- 循环之谜
- 异常之迷
- 类之迷
- 库之迷
- 更多类之谜
- 更多库之迷
- 高级谜题