3.3 数据类型
java 是强类型语言 所以就意味着必须为每一个变量声明一种类型
3.3.1整型
java中 整型的范围与运行JAVA代码的机器无关 C和C++需要针对不同的位处理器选择最为有效的整型 否则就有可能造成一个在32位处理器上运行很好的C程序在16位处理器上出现整数溢出 长整型有后缀L 十六进制数值有一个前缀0X 8进制数值有个前缀0 所以八进制比较容易混淆 所以建议不要使用八进制
3.3.2浮点类型
很多情况下float类型的精度很难满足需求 float类型有一个后缀F 默认的浮点类型是double 当然也可以再double后面加上D
在十六进制表示法中 使用p表示指数 而不是e
0.125可以表示成0x1.0p-3
所有的浮点数值计算都遵循IEEE754规范 下面表示溢出和出错情况的三个特殊浮点数值
正无穷大 ( 例如一个正整数除以0)(常量Double.POSITIVE_INFINITY)
负无穷大 (常量Double.POSITIVE_INFINITY)
NaN(Not a Number)(0/0或者负数的平方根)(常量Double.NaN)
3.3.3char类型
用来表示单个字符 通常用来表示字符常量 unicode编码单元可以表示为十六进制值 其范围从
\u0000到 \uffff
想要弄清char类型 就必须了解unicode编码表
在java中 char类型用UTF-16编码描述一个代码单元
3.4 变量长度
变量名的长度没有限制
检测那些unicode字符属于java中的字母 用这两个方法
System.out.println(Character.isJavaIdentifierPart('s'));// true
System.out.println(Character.isJavaIdentifierPart('^'));// false
3.5 运算符 数据类型转换,强制转换,枚举类型
当参与运算的两个操作数都是整数时 表示整数运算 否则表示浮点运算
整数被除0将会产生一个异常 而浮点数被除0将得到无穷大或者NaN
System.out.println(-3.2/0);//-Infinity
对于浮点数的算数运算 实现JAVA的可移植性(不同平台得到的结果是一样的)是相当困难的 double类型使用64位存储一个double数值 而有些处理器处用80位来进行存储 这些寄存器增加了中间过程的计算精度 double w = x*y / z;
很多intel处理器 计算x*y 并且将结算结果存储在80位寄存器中 再除以z并且将结果截断成64位 这样可以得到一个更加精确的结果 并且还能避免指数溢出 但是在始终在64位机器上计算的结果可能于它不一样 所以java在默认情况下虚拟机设计者允许将中间计算结果采用扩展的精度 但对于使用strictfp关键字标示的方法必须使用严格的浮点计算来产生理想的结果
public static strictfp void main(String[] args)
如果这个关键字标记在类中 那么这整个类都需要严格的浮点计算
实际的计算方式将取决于intel处理器 在默认情况下 中间结果允许使用扩展的指数 但不允许使用扩展的尾数
3.5.3 位运算符
^异或
~非
>> , <<运算符将二进制位进行右移或左移操作
对移位运算符右侧的参数需要进行模32的运算(除非左边的操作数是long类型 在这种情况下需对右侧操作数模64) 1<<35,1<<3效果是一样的
>>>运算符用0填充高位 没有<<<
·
&:相同位的两个数字都为1,则为1;如果有一个不为1,则为0。这可以用来判断一个整数的奇偶,如果末位为0表示该数为偶数。
· |:通常用于二进制特定位上的无条件赋值,例如一个数or1的结果就是把二进制最末位强行变为1。如果需要把二进制最末位变为0,or1后再-1就可以了。其实实际意义就是把这个数强行变成最接近的偶数。
·^(异或):操作的结果是相同某位不同则该位为1,否则为0.
System.out.println(7^1);//6
·~(not运算,取反)
:not运算的定义是把内存中的0和1全部取反。
3.5.5 数值类型之间的转换
当使用两个不同数据类型的数值进行二元操作时,例如n+f,n是整数,f是浮点数,先要将两个操作数转换为同一种类型。然后再进行计算。
·如果两个操作数中有一个是double类型的,另一个操作数就会转换为double类型。
·否则,如果其中一个操作数是float类型,另一个操作数将会转换为float类型。
·否则,如果其中一个操作数就long类型,另一个操作数将会转为为long类型。
·否则,两个操作数都会转换为int类型。
PS:二元运算属于数学运算的一种。二元运算需要三个元素:二元运算符以及该运算符作用的两个变量。如四则运算的加、减、乘、除均属于二元运算。
如在运算1 + 2之中,二元运算符为“+”,而该运算符作用的操作数分别为1与2。
数就long类型,另一个操作数将会转为为long类型。
·否则,两个操作数都会转换为int类型。
精度损失
下图非强制转换,属于计算中的类型转换,虚线代表精度会损失.
从概念上讲 java字符串就是unicode字符序列
java没有内置的字符串类型 而是在标准java类库中提供了一个预定义类String
3.6.3 不可变字符串
String类没有提供用于修改字符串的方法 但是不可变字符串有一个优点 编译器可以让字符串共享(可以想象各种字符串存放在一个公共池中 字符串变量指向存储池中相应的位置)
3.6.5代码点与代码单元
String用char序列组成
String.length将返回采用UTF-16编码表示的给定字符串所需要的代码单元数量
java以独特的风格对字符串中的代码单元计数 :字符串中第一个代码单元位置为0 这种习惯起于C
但有的字符使用UTF-16需要两个代码单元 调用charAt(1)返回的可能不是后一个字符 而是第二个代码单元 如果想遍历一个字符串 并且一次查看每一个代码点 可以使用下列语句
public static void main(String[] args) {
String sentence = "\u03C0 \uD835\uDD6B";
// System.out.println(sentence);
// System.out.println(sentence.length());
bianl(sentence);
}
public static void bianl(String inputStr){
for(int i=0 ;i<inputStr.length(); i++){
int cp = inputStr.codePointAt(i);
if(Character.isSupplementaryCodePoint(cp)){
i+=2;
}else{
i++;
}
System.out.println(i);
}
}
UTF-8的8指的就是最小为8位一个单元,也即一字节为一个单元,UTF-8可以包含一个单元,二个单元,三个单元及四个单元,对应即是一,二,三及四字节。
UTF-16的16指的就是最小为16位一个单元,也即二字节为一个单元,UTF-16可以包含一个单元和二个单元,对应即是二个字节和四个字节。我们操作UTF-16时就是以它的一个单元为基本单位的。
同理,UTF-32以32位一个单元,它只包含这一种单元就够了,它的一单元自然也就是四字节了。
3.6.8构建字符串
采用字符串连接的效率比较低,因为每次都会产生一个新的字符串,这种情况下可以使用Stringbuilder进行连接,当每次需要添加一部分内容时,就调用append方法,在需要构建字符串的时候就执行toString方法。其效率要比Stringbuffer高(StringBuffer是线程安全的)。
ss