细节扫盲 第一篇
数值型
- byte和short:主要用于特定的应用场合,例如,底层的文件处理或者存储空间很宝贵时的大数组;
- java7开始,可以使用前缀代表进制,0B或0b代表二进制;0X或0x代表十六进制;0代表八进制,如,010对应十进制中的8,容易混淆,不建议使用;还可以在数字之间加下划线_,编译器会自动去除,如,1_000_000,能方便阅读。
- java没有无符号的整数型,需要使用无符号时,请使用封装类的无符号方法。
- 没有F后缀的浮点数值,如3.14,默认是double类型,而不是float类型。
- 可以使用十六进制表示浮点数值。
例如,0.125=2-3可以表示成:0x1.0p-3,p表示指数,而不是e(e是一个十六进制数位)。
注意:尾数采用十六进制,指数采用十进制,指数的基数是2,而不是10。 - 用于表示溢出和出错的特殊常量:正无穷大(如Double.POSITIVE_INFINITY)、负无穷大(如Double.NEGATIVE_INFINITY)、NaN(如Double.NaN,表示不是一个数字),NaN判断需要使用isNaN方法。
例如,一个正整数除以0的结果为正无穷大,计算0/0或者负数的平方根结果为NaN。 - 浮点数float和double有精确度问题,在二进制中无法精确表示1/10,跟十进制的1/3一样无法精确表示,故在对数值有精确要求的情况下不要使用float和double,应使用BigDecimal。
- 在循环中,检测两个浮点数是否相等需要格外小心。
for(double x=0;x!=10;i++)
由于舍入误差,可能永远达不到精确的最终值,从而永远不会结束。
算术运算
- 除法(/)算术运算时,两个操作数都是整数时,表示整数除法,否则表示浮点除法。除0运算则会异常。
- 关键字strictfp:使浮点计算采用严格模式,会截断中间计算(扩展计算),从而保证不同位数的计算机的计算结果一致。
说明:是为了统一不同位数处理器的结果,如80位浮点寄存器得出的结果会比64位的计算更精确,但是可能会导致运算结果不一致,为了一致性,应该使用该关键字。
- 除了简单的加减乘除运算,建议都使用Math工具类,取模也尽量使用Math工具。(同时,还有一个StrictMath工具类,该类跟关键字strictfp的要求一样,保证不同位数的计算机的计算结果一致。)
例如,n%2,当n为负时,得到的余数为负数,floorMod方法可以解决,但遗憾的是,负除数会得到负数。
char:
-
原用于表示单个字符,但由于扩展后的字符集(辅助字符,如 U+1D546, 𝕆 )超过char能表示的范围,故现在有些字符需要2个char表示;
-
Unicode转义序列会在解析代码之前得到处理,所以即使在注释中,也会生效;
\u是Unicode转义开始符号;
注释语句 :
// \u000A 是换行符的Unicode码, 会产生语法错误,因为会换行,导致无法被注释;
// look c:\users 也会有语法错误,因为\u后面没有跟4个十六进制。
类型转换
合法转换:(可自动转换)
byte–>short–>int–>long
char–>int
int–>double
int–>float(可能有精度损失的转换)
long–>float(可能有精度损失的转换)
long–>double(可能有精度损失的转换)
float–>double
规律:短长度(位数)向长长度转换,则无精度损失;同长度的整数型向浮点型转换,则可能会精度损失;long转float是合法转换;
精度损失的根本原因就是长度(位数)表示范围的限制;
强制类型转换:
规律:除了long转float是合法转换外(个人觉得很奇怪,觉得不合理),其余长长度向短长度类型转换,浮点数转换成整数型,都需要强制转换,因为根据应用场景,这会大概率的丢失精度。
精度丢失的表现:如果实体讲一个数值从一种类型强制转换为另一种类型,而又超出了目标的表示范围,结果就会截断成一个完全不同的值。例如,(byte)300的实际值为44;
所以,尽量不要使用强制类型转换;通常强制类型转换都用在特殊需求上,如,只要浮点型数值的整数位,那么这时可以强制类型转换截断小数。
String:
- 底层是char[];
- 由于辅助字符需要2个char表示,故不应该直接使用char方法进行字符获取,应该使用codepoint方法。
- codepoint是代表一个完整字符(常用字符和辅助字符)
- 特点:有返回值的方法,返回的都是新的对象,故通常做动态拼接时,不推荐使用,应使用StringBuffer或StringBuilder;但若是多个固定字符串做拼接,则编译器在生成class时会自动做拼接处理,如:String a=“a”+“b”;生成的class文件,String a=“ab”;
- 特殊:字符串字面量(这种定义方式String a=“a”;)是共享(地址相同)的,而+或substring等操作得到的字符串不共享,所以"= ="(只能判断地址是否相同)在纯字符串字面量的判断中是成立的,但大多数情况下不适用。且String是普通对象类,不是基本数据类型,所以equals才是能准确判断两个类的值是否相等的方法。
- 方法参数CharSequence(接口):所有字符串都属于CharSequence接口,所以看到CharSequence,可以传入String实参。