目录
类型分类概述
分为4个大类:整型,字符类型,浮点型,布尔类型。
如果硬要说,字符类型也可以作为2字节的无符号整型,所以说一共有3类也行。
java是强类型语言,每种类型都有清晰准确的规定,规定清楚了字段宽度和取值范围,在任何平台都统一。
下面详细讲解每种类型的细节。
整型
整型类型宽度和取值范围
java的整型和C++不同,它的宽度和取值范围都是固定的,而且java没有无符号类型unsigned这种说法。
如下表所示:
类型 | 宽度 | 范围 |
---|---|---|
byte | 8位 | -128 ~ 127 |
short | 16位 | - 2 15 2^{15} 215 ~ 2 15 2^{15} 215 - 1 |
int | 32位 | - 2 31 2^{31} 231 ~ 2 31 2^{31} 231 - 1 |
long | 64位 | - 2 63 2^{63} 263 ~ 2 63 2^{63} 263 - 1 |
整型字面量
整型字面量就是字面值和含义一样的量。比如312,4303943894L等
整型字面量的表示形式
整型字面量根据基数不同有4种表示形式,用不同的前缀来区分。0B或者0b开头的是二进制的字面量,0开头的是8进制的字面量,无前缀的是十进制的字面量,0x或者0X开头的是十六进制的字面量。
注意表示形式和内存中的存储方式是两回事,内存中所有整数都以二进制的补码形式存储。
整型字面量的类型
java的整型字面量默认为int类型,但是具体分2部分去理解:
1.假如将整型字面量赋值给byte和short类型,同时该字面量的值在对应类型的范围内,那么字面量会自动转换为对应的类型;如果字面量的值超出了该类型的范围,就会报错。
比如byte b1 = 127; 127在byte的范围内,而127要赋值给byte变量,那么127这个字面量就会被转换为byte类型。
但是如果是byte b1 = 128;那么128不在byte范围内,却要直接赋值给一个byte类型的变量,那么就直接报错。
2.对于超过int范围的字面量,想赋值给long类型比如加后缀L或者l。
比如3_000_000_000,它超过了int的最大值,系统不会把30亿默认为long类型。
对于代码long l1 = 3_000_000_000; 系统会直接报错。
如果要想成功赋值给long类型的变量,必须加后缀L或者l。代码应该改为:long l1 = 3_000_000_000L;
总结就是:小整数会根据赋值的变量类型自动转换,大整数必须加后缀L。
字符类型
字符类型通过编码的方式将字符映射为对应的二进制数,存储到计算机中。
java的编码方式为Unicode编码,为2个字节,一共16位,所以char类型的宽度为2个字节,最多可以表示65536个字符。
字符类型的符号
char类型也可以当做2字节的整数处理,它是无符号类型,可以表示0~65535这个范围的整数。
字符字面量
char的字面量有3种表示形式,和C++是类似的。
1.把字符包含在单引号内的方法,比如’A’,'b’等,char类型变量存储的是对应字符的二进制编码。
2.转义字符表示无法从键盘输出的字符或者有特殊用途的字符。
需要记住的转义字符请看下面的表格:
字符名称 | C++代码 |
---|---|
换行符 | \n |
水平制表符 | \t |
反斜杠 | \\ |
单引号 | \’ |
双引号 | \" |
3.用Unicode编码表示的字符型的值,格式为:‘\uxxxx’,xxxx是4个十六进制的数字,该数字表示在Unicode中对应的字符。
比如’\u9997’这种格式。
浮点类型
java的浮点类型分为2类:float和double。用来表示小数。
浮点类型的精度和字段宽度
两种浮点类型都有固定的精度和字段长度。
float一共有32位,1位是符号位,8位是指数位,剩下23位是小数位。
double类型一共有64位,1位是符号位,11位是指数位,剩下52位是小数位。
浮点数在内部是以二进制分为2部分存储的,指数和尾数部分都分开用二进制存储。指数位的幂不是十进制的幂,而是二进制的幂。
由于精度有限,所以当小数的尾数特别长时,可能会出现误差。
浮点字面量
浮点字面量是带小数点的数字。可以给浮点类型的变量赋值。
浮点字面量的表示形式
有2种表示形式:
1.十进制的小数形式。
也就是最常见最直观的数学形式的表示。比如0.12等。
2.E表示法
这种表示法类似数学的科学计数法。
分为2部分,左边表示尾数,右边表示指数。指数的幂是10进制的,符合程序员的习惯。
比如3.2E3,等价于320.0。
浮点字面量的类型
浮点字面量默认是double类型,如果需要转为float类型,比如加后缀F或者f。
3个浮点字面量的特殊值
有3个特殊值,分别是:正无穷,负无穷和非数。
正无穷:任何正的浮点数数除以0就会得到正无穷。
负无穷:任何负的浮点数除以0就会得到负无穷。
正无穷和负无穷是Java的Double类和float类定义的常量,正无穷是Double.POSITIVE_INFINITY和Float.POSITIVE_INFINITY;负无穷是Double.NEGATIVE_INFINITY和Float.NEGATIVE_INFINITY。
注意,任何正无穷都是相等的(不用管它是Double类里面的还是Float类里面的)。
任何负无穷也都是相等的。
还要注意,正无穷和负无穷是浮点数的特殊值,必须用浮点数除以0得到,整数除以0会直接报异常。
非数:0.0除以0.0或者对负数开方会得到一个非数。非数表示为Double.NaN或者Float.NaN。
值得注意的是,任何非数都不相等。比如Double.NaN甚至和Double.NaN都不相等。
布尔类型
布尔类型只有一种类型:boolean类型(注意和C++的bool区分)。用于表示逻辑的真和假。
与C++不同的是,布尔类型的值只有true和false,与非零的整数和零没有任何对应关系。不能用0代表假,非零代表真。
布尔类型的字段长度
JAVA没有确切规定布尔类型的长度,虽然只需要1个bit,但实际往往根据当前系统允许分配的最小内存单元决定,很多系统都是1个字节。
var类型
这是一种动态类型,var类型的变量具体是什么类型,由初始化右边的值决定。
var这种类型在java中出现我并不觉得有很大的价值,因为java是强类型语言,每种类型都有准确的规定,任何平台都统一。
var这种动态类型本质还是强类型,只不过确定类型的方式由初始值决定,一旦确定,该变量的类型就确定了。
比如var num = 5; 5这个字面量默认是int类型,所以num变量就是int类型了。
再比如var a1 = 3.14; 3.14默认是double类型,所以a1变量就是double类型了。
定义var类型的变量必须初始化,否则编译器无法确定该变量的类型。
var如果不谨慎使用反而有害!
如果var类型的变量初始化的值来源于某个方法的返回值,程序员很难一眼确定该变量的真正类型,从而降低了可读性。