一、Java中的基本数据类型
java中有8种基本数据类型,包括:6种数字类型、1种字符类型、1种布尔类型:
1) boolean:1个bit。true/false,java中默认值false
2) char:2Byte的Unicode 字符(Java采用UniCode,2个字节来表示一个字符),java中默认值'u0000'
3) byte:1Byte,有符号数,java中默认值0
4) short:2Byte,有符号数,java中默认值0
5) int:4Byte,有符号数,java中默认值0
6) long:8Byte,有符号数,java中默认值0
7) float:4Byte,浮点数,java中默认值0.0f
8) double:8Byte,浮点数,java中默认值0.0d
Java中的基本类型的字节长度是和平台无关的。
1、boolean类型
注:java中的boolean类型使用比其他语言严格的多,boolean类型即不能是整数也不能是对象。如:
Object 0 = new Object();
int i = 1;
if(o)、if(i)使用方式都是不合法的。需要使用if(o != null)
2、字符型
java中的字符型,支持三种方式表达:
(1)把字符放到单引号内。
(2)字符对应的Assic数值,可以是十进制、二进制、八进制、十六进制。
(3)也可使用unicode转义序列。
(4)也可使用特殊转义字符。
如:
Tab键:' '
nul:' 000’
aleph:'u05D0’
slash:'\’
更多转义字符:
退格符
水平制表符
换行符
f 换页符
回车符
” 双引号
’ 单引号
\ 反斜杠
xxx xxx是8进制,表示Latin-1字符
uxxxx xxxx是十六进展数,标识Unicode字符。
(1)其中Unicode码采用uxxxx形式表示一个字符。这种表示法只限于码点在u0000~uFFFF之间的字符。超出这个范围的字符,必须用两个双字节的形式表示,如:uD842uDFB7。
(2)Unicode码不能省略前面的几位0,如:'u20'在java中会报错。
3、整数类型
byte、short、int、long四种类型,每种类型都是有符号,只是标识范围不同。
支持十进制、十六进制、八进制、二进制标识。
0x 0X开头,表示十六进制
0b开头,表示二进制
0开头,标识八进制
123L 表示是Long类型数字。
如果运算结果超出了变量范围,会如何?
Java中不会上溢或下溢,而是直接回绕,如:
byte b1 = 127, b2 = 1; //byte类型的最大值是127
byte sum = (byte)(b1 + b2); //加法运算的结果直接回绕到-128,即byte类型的最小值
如果发生了这种情况,Java 编译器和解释器都不会发出任何形式的警告。进行整数运算时,必须确保使用的类型取值范围能满足计算需要。
4、浮点类型
包含float、double
浮点数的字面表示格式,如:
123.45
1.1
.12
1e-6
默认字面的浮点数都是double的,如果需要使用float的字面数,需要添加f标识。如:123.45f
浮点数比较的方法:Math.abs(a - b) < 1E-6F
所以,如下采用浮点数作为循环变量,在Java中实际会导致死循环(float和dobule不能作为for语句的循环变量)。如:
for(float f =100000000;f<100000010;f++){
System.out.println(f);
}
实际测试是死循环。
注:如果浮点数的运算结果超出了float或double的范围上限,得到的是无穷大。如果浮点数运算结果超出了float或double的范围下限,得到的是无穷小。
浮点数运算中有个特殊值NaN,标识Not a number,如果浮点数运算不合法(如:0.0/0.0),得到的是NaN。
Java 浮点数类型能处理到无穷大的上溢以及到零的下溢,因此浮点数运算从不抛出异常, 就算执行非法运算也没事,例如零除以零,或计算负数的平方根。
注意:禁止尝试与NaN进行比较运算,相等操作使用double或float的isNaN方法。
NaN(Not a Number,非数值)是无序的,
(1)当一个或两个操作数是NaN时,数值比较符<、<=、>、>=会返回false。
(2)当任意一个操作数是NaN,==运算符会返回false
(3)当任意一个操作数是NaN时,!=运算符会返回true。
因为无序的特性常常会导致意外结果,所以不能直接与NaN进行比较。使用方法Double.isNaN(result)方法来检查result是否为一个NaN数值,可以获得正确的结果。
二、java中基本数据类型之间的转换
1、自动类型转换(隐式转换):
Java的基本类型运作过程中可以混合使用,Java会自动进行类型转换:byte/short/char → int → long → float → double
什么情况下不能隐式转换:如果会丢失精度,则不能隐式转化,比如long转int或者double转long这种。编译器会强制我们使用强制转化。
2、强制类型转换:
样例:
int i = 3;
byte b = (byte)i;
在java中,允许:
1) 整数和浮点数之间相互转换
2) 字符型 和 整数/浮点数之间相互转换
3) boolean类型不能相互转换
放大转换:把某种类型转换为取值范围更广的类型。如:int转换为double
缩小转换:把某种类型转换为取值范围没那个广的类型。缩小转换可能会导致丢失数据,是不安全的。所以缩小转换时java编译器会发生告警。
浮点数转换为整数,浮点数的小数部分会被直接截掉,而不是四舍五入。
如果采用其他的舍入方式,请使用如下Java中的数据运算封装类的方法:Math.round()、Math.floor()、Math.ceil()。
字符和整数转换,如下很有趣:
short s = (short) 0xffff; // 这些比特表示数字-1
char c = 'uffff'; // 还是这些比特,表示一个Unicode字符
int i1 = s; // 把short类型转换成int类型,得到的是-1
int i2 = c; // 把字符转换成int类型,得到的是65535
三、java中运算符
1、运算符种类
类同C、C++。
1) 算术运算符
+ - * / % ++ --
2) 条件运算符:
== != > < >= <=
3) 位运算符:
Java中位运算符应用于char、byte、short、int、long类型。
& | ^ ~ << >> >>>
4) 逻辑运算符:
&& || !
5) 赋值运算符
= += -= *= /= (%)= <<= >>= &= ^= |=
6) 条件运算符
? :
样例:a>b?a:b;
7) instanceof运算符:
检查该对象是否是一个特定类型(Class类型或接口类型)。
如:String name="James";
boolean result= name instanceof String; //name是String类型,所以返回true
8) 特殊运算符
lambda表达式(->)
2、运算符优先级
注:Java 解释器计算表达式时,会按照表达式中的括号、运算符的优先级和结合性指定的顺序运算。不过,在任何运算之前,解释器会先计算运算符的操作数。
如:
int a = 2;
int v = ++a + ++a * ++a;
java解释器会先计算操作数,所以这个表达式实际上是:3 + 4 * 5,结果 为 23。
3、Java中运算符的返回值类型
- 参与运算的任一操作数是dobule类型,运算结果返回值就是double类型。否则:
- 参与运算的任意操作数是float类型,运算结果返回值就是float类型。否则:
- 参与运算的任意操作数是long类型,运算结果返回值就是long类型。否则:
- 运算返回结果值都是int类型,即使参与运算的操作数是byte、short、char。
- 相等、逻辑运算符返回boolean型。
So、如下例子就很有趣:
byte b1 = 5;
byte b2 = 1;
short s1 = b1 + b2; //编译报错。因为b1 + b2两个byte类型相加,最终结果是int类型。int类型不能默认转换为short类型。
short b1=5;
short b2=1;
short b3 = b1 + b2; //编译报错。因为b1 + b2两个short类型相加,最终结果是int类型。 从int转换到short可能会有损失