一、比特(bit)和字节(byte)
- 计算机就是一系列的电路开关。每个开关存在两种状态:关(off)和开(on)。如果电路是开的,它的值是1。如果电路是关的,它的值是0
一个0或者一个1存储为一个比特(bit),是计算机中最小的存储单位
- 计算机中是最基本的存储单元是字节(byte)。每个字节由8个比特构成
- 计算机的存储能力是以字节和多字节来衡量的
- 千字节(kilobyte,KB)=1024Byte(字节)
- 兆字节(megabyte,MB)=1024KB
- 千兆字节(gigabyte,GB)=1024MB
- 万亿字节(terabyte,TB)=1024GB
二、基本数据类型
对于每一种数据都定义了明确的具体数据类型(强类型语言),在内存中分配了不同大小的内存空间
1、整数类型:byte、short、int、long
- byte占用8个bit位,共2^8^=256个表达方式,负数(128个):-1~-128 正数(128个):0~127
- java的整型常量默认为int型,声明long型常量须后加
‘l’或‘L’
2、浮点类型:float、double
- 浮点型常量有两种表示形式:
- 十进制数形式:如:5.12、512.0f、 (必须有小数点)
- 科学计数法形式:如:5.12e2、512E2、100E-2
- float:
单精度
,尾数可以精确到7位有效数字。很多情况下,精度很难满足需求 - double:
双精度
,精度是float的两倍。通常采用此类型 - 定义float类型的变量,赋值时需要以"
f
"或"F
"作为后缀 - float表示数值的范围比long还大
关于浮点型精度的说明
- 并不是所有的小数都能可以精确的用二进制浮点数表示
- 二进制浮点数不能精确的表示0.1、0.01、0.001这样10的负次幂
- 浮点类型float、double的数据不适合在
不容许舍入误差
的金融计算领域 - 如果需要
精确
数字计算或保留指定位数的精度,需要使用BigDecimal类
double测试用例:
System.out.println(0.1 + 0.2);//0.30000000000000004
- 整数变为二进制,能够做到“每个十进制整数都有对应的二进制数”
- 比如数字3,二进制就是11
- 再比如,数字43就是二进制101011,这个毫无争议。
- 对于小数,并
不能
做到“每个小数都有对应的二进制数字”- 举例来说,二进制小数
0.0001表示十进制数0.0625
(至于它是如何计算的,不用深究) - 二进制小数
0.0010表示十进制数0.125
- 二进制小数
0.0011表示十进制数0.1875
- 举例来说,二进制小数
- 对于四位的二进制小数,二进制小数虽然是连贯的,但是十进制小数却不是连贯的
- 比如,你无法用四位二进制小数的形式表示0.125~0.1875之间的十进制小数
float测试用例:
float ff1 = 123123123f;
float ff2 = ff1 + 1;
System.out.println(ff1); // 1.2312312E8
System.out.println(ff2); // 1.2312312E8
System.out.println(ff1 == ff2); // true
3、字符类型:char
- char 型数据用来表示通常意义上字符(
占2字节
) - Java中的所有字符都使用
Unicode编码
,故一个字符可以存储一个字母,一个汉字,或其他书面语的一个字符- Unicode常用字符2字节,对于4字节的扩展字符用char表示编译就会报错;如String str1 = '🤣';
- 字符型变量的四种表现形式如下:
形式一:使用单引号(' ')括起来的
单个字符
//使用一对''表示,内部有且仅有一个字符
char c1 = 'a';
char c2 = '中';
char c3 = '1';
char c4 = '%';
char c5 = 'γ';
//编译不通过
//char c6 = '';
//char c7 = 'ab';
形式二:使用
Unicode值
来表示字符型常量
- ‘
\uXXXX
’,其中,XXXX代表一个十六进制整数
,转为十进制与ASCII表兼容 - 如下unicode表,纵坐标 + 横坐标 如:@用0040来表示
形式三:使用
转义字符‘\’
来将其后的字符转变为特殊字符型常量
- 如:char c3 = '\n'; 表示换行符
转义字符 | 说明 | Unicode表示方式 |
---|---|---|
\n |
换行符 | \u000a |
\t |
制表符 | \u0009 |
\" |
双引号 | \u0022 |
\' |
单引号 | \u0027 |
\\ |
反斜线 | \u005c |
\b |
退格符 | \u0008 |
\r |
回车符 | \u000d |
形式四:使用具体字符对应的数值(比如
ASCII码
)
char c11 = 97;
System.out.println(c11);//a
- char类型是可以
进行运算
的。因为它都对应有Unicode码,可以看做是一个数值
char c12 = '1'; // ASCII对应数字49
char c13 = 65; // 这里就是ascii码65,对应字符A
System.out.println(c12+c13); // 49+65=114
4、布尔类型:boolean
- boolean类型用来判断逻辑条件
- boolean类型数据只允许取值true和false,
无null
拓展——《java虚拟机规范 8版》
- Java虚拟机中没有任何供boolean值专用的字节码指令
- Java语言表达所操作的boolean值,在编译之后都使用java虚拟机中的
int数据类型
来代替 - true用1表示,false用0表示
- 虽然可以用一个bit(八分之一字节)表示1或0,但是会用int表示,也就是
占用4个字节
三、基本数据类型转换
- 自动类型转换:
容量小
的类型自动转换为容量大
的数据类型。数据类型按容量大小排序为:- 说明:此时的容量小或大,并非指占用的内存空间的大小,而是指表示数据的范围的大小(long8字节、float4字节)
// 编译通过
int i1 = 10;
int i2 = i1;
long l1 = i1;
float f1 = l1;
double d1 = f1;
- byte,short,char之间不会相互转换,他们三者在计算时首先转换为
int类型
// 计算时,b1已经转换为int类型
byte b1 = 12;
int i3 = b1 + i1;
//编译不通过 b1已经转换为int类型,应该用int类型接收
// byte b2 = b1 + i1;
//特殊的情况:byte、short之间做运算
byte b3 = 12;
short s1 = 10;
// 编译不通过 需要用int来接收
//short s2 = b3 + s1;
int i4 = b3 + s1;
- boolean类型不能与其它数据类型运算
- 当把任何基本数据类型的值和字符串(String)进行连接运算时(+),基本数据类型的值将自动转化为字符串(String)类型
- 自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。
使用时要加上强制转换符:()
,但可能造成精度降低或溢出
// 自动类型提升
double d1 = 12;
// 编译失败
// int i1 = d1;
int i2 = (int) d1;
System.out.println(i2);
long l1 = 123;
// 编译失败
// short s1 = l1;
short s2 = (short) l1;
System.out.println(s2);
// 精度损失的例子1:
double d2 = 12.9;
int i4 = (int) d2;
System.out.println(i4);// 12
为什么标识符的声明规则里要求不能数字开头?
//如果允许数字开头,则如下的声明编译就可以通过:
int 123L = 12;
//进而,如下的声明中l的值到底是123?还是变量123L对应的取值12呢? 出现歧义了。
long l = 123L;