数据类型:它定义了变量或表达式可以存储数据的种类。
java是一种强数据类型语言
一、基本数据类型
1.byte
byte 在多种编程语言中用于表示一个8位(即1字节)的整数。由于它是8位的,因此 byte 类型的变量可以存储的值的范围是 -128 到 127(在有符号字节的情况下)或 0 到255
2.short
short用于表示16位有符号整数,固定占用2个字节(16位)的内存空间。
short s = 100;
3.int
int用于表示32位有符号整数,固定占用4个字节(32位)的内存空间。
int类型的变量如果不赋初始值,默认为0。
4.long
long用于表示64位有符号整数,固定占用8个字节(64位)的内存空间。与int类型相比,long类型通常占用更多的内存空间,因此能够表示更大的整数范围。
5.float
float类型用于存储单精度浮点数,通常占用4个字节(32位)的内存空间。
float a = 3.14;
6.double
double类型用于存储双精度浮点型,且其精度高于单精度浮点数,通常占用64位(8字节)的内存空间。
double a = 3.14159;
7.boolean
boolean类型用于表示逻辑上的真(true)或假(false)。
8.char
char
类型是计算机编程语言中用于表示单个字符的基本数据类型。它在java当中通常占用2个字节(16位)的内存空间,并可以表示ASCII码表或Unicode码表中的字符。
java字符类型采用Unicode字符集编码。Unicode是世界通用的定字长字符集,所用字符都是16位
public static void main(String[] args) {
char c1 = '中';
char c2 = '\u4e2d';
System.out.println(c1);
System.out.println(c2);
}//输出结果全为 中
其中u4e2d为Unicode字符集内,字符 中 所对应的16位二进制编码值
任何一个字符都可以转化为一个整数,整数的范围是0-65535
public static void main(String[] args) {
int a = '中';
System.out.println(a);
}
可以查看某个数对应着那个字符
public static void main(String[] args) {
char c = 69;
System.out.println(c); //输出结果为 E
转义字符
对于不方便输出的字符可以采用转义字符表示:
例如:
public static void main(String[] args) {
int num = 100;
String json = "{"+"\"count\":"+num+"}";// /斜杠 \反斜杠
String dataString = "[{\"id\":\"1\" ,\"name\":\"张三\"},{\"id\":\"2\" ,\"name\":\"李四\"},{\"id\":\"3\" ,\"name\":\"王五\"}]";
System.out.println(json); //输出结果为 {"count":100}
}
----------------------------------------------------------------------------------------------------------------
转义字符 含义
\n 表示回车
\r 表示换行符
\\ 表示反斜杠( \ )
\' 表示单引号( ' )
\" 表示双引号( " )
---------------------------------------------------------------------------------------------------------------------
内存空间分布
二、计算机对整型数据的存储方式
整数转换为二进制,数据类型决定数据在内存当中如何存储,如byte类型大小是8bit(1字节)由1bit符号位和7bit数值位组成
1、二进制表示
计算机内部使用二进制(0和1)来表示所有的数据,包括整型数据。每个二进制位(bit)代表2的幂次方的值,从右到左(或从低位到高位)依次增加。
首先,确定整数是正数还是负数。正数的符号位为0,负数的符号位为1。
除2取余法:对于非负整数,可以通过不断除以2并取余数的方法来得到其二进制表示。从整数开始,不断除以2,每次迭代都记录余数(0或1),直到商为0。然后,将得到的余数序列逆序排列,就是该整数的二进制表示。需要注意的是数据的类型,不同数据的类型数据长度不同,最高位为符号位,若余数逆序排列加符号位长度不够,在符号位和数值间补零至满足其长度。
拆分法:将这个数据拆分成2^n次方相加模式,如正数28可以拆分为16+8+4,即2^4+2^3+2^2,可转换为1 1100
2、原码、反码、补码
原码:就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值。原码的相反数相加不是0
反码:正数的反码是其本身,负数的反码是在其原码的基础上,符号位不变,其余各位取反。反码存在+-0的问题
补码:正数的补码是其本身,负数的补码是在其原码的基础上,符号位不变,其余各位取反后加1(即在反码的基础上+1)。计算机内部使用补码来表示和存储数据,因为补码可以有效地处理正负数的加法运算。
ege:byte a = 10; 00001010 (原码);00001010 (反码);00001010 (补码)
byte b = -10; 10001010 (原码);11110101 (反码);11110110 (补码)
a+b的补码为:1 0000 0000 因为数据类型规定了数据在内存当中的存储大小,此时需要截取数据:--->1 0000 0000(补码)
0000 0000(补码) ------------->00000000(原码) = 0
3、溢出
byte a =127;
byte b =1;
byte c =(byte)(a+b);
System.out.println(c); //c的值为-128
两个 byte 类型的变量进行加法运算时,结果的类型会自动提升为 int类型
a 的值是 127(在二进制中表示为 0111 1111)。
b 的值是 1(在二进制中表示为 0000 0001)。
当你执行 a + b 时,由于类型提升,这个操作实际上是在 int 类型的上下文中进行的。因此,127 + 1 的结果是 128,在 int 类型的二进制表示中,128 是 0000 0000 0000 0000 0000 0000 0100 0000。
但是,当你尝试将这个 int 类型的结果赋值给 byte 类型的变量 c 时,你必须进行显式的类型转换,即 (byte)(a + b)。在这个转换过程中,Java 会丢弃 int 值的最高位(即所有除了最低的8位之外的所有位),只保留最低的8位。
由于 128 在 int 中的二进制表示是 0000 0000 0000 0000 0000 0000 0100 0000,当只保留最低的8位时,你得到的是 1000 0000。在 byte 的上下文中,这个二进制值表示的是 -128,因为最高位(符号位)是 1,表示这是一个负数,而剩下的7位(1000 000)在二进制补码表示法中对应于 128 的绝对值(但因为是负数,所以实际值是 -128)。
所以,c 的值是 -128。
三、计算机对浮点数数据的存储方式
float:单精度类型 1bit 8bit 23bit 32bit
double:双精度 1bit 11bit 52bit 64bit 默认
小数转换为二进制:
小数部分使用乘2取整法,即将小数部分乘以2,然后取结果的整数部分,再用得到的新小数部分重复此过程,直到小数部分为0或达到所需的精度为止。
1、浮点数精度丢失
public class Client {
public static void main(String[] args) {
System.out.println(1.2-1); //输出结果为 0.19999999999999996 不为0.2
}
}
原因:
二进制:0.2---->0.0011001100110011.......
计算机把0.2转换为二进制的过程中,超过浮点数能存储的数据长度,使其数据丢失
避免方法:
public class Client {
public static void main(String[] args) {
//System.out.println(1.2-1);
BigDecimal b1 = new BigDecimal(Double.toString(1.2)); //BigDecimal 精度强相关
BigDecimal b2 = new BigDecimal(Double.toString(1));
Duble value = b1.subtract(b2).doubleValue(); //b1.subtract(b2).doubleValue() b1减去b2 并将其值转换为double类型
System.out.println(value); 输出结果为0.2
}
}
四、数据类型转换
转换的方式有两种:自动类型转换和强制类型转换
1、自动类型转换(大碗装小碗)
整型、实型、字符型数据可以混合运算,但是在运算时,不同类型的数据须先转换成同一类型。
2、强制类型转换(小碗装大碗)
如果程序要求一定将某一类型的数据从该种类型强制地转换为另一种类型,则需要人工编程进行强制类型转换,也称为显式转换。
public class Client {
public static void main(String[] args) {
int a = 10;
byte b =(byte) a; //a为int类型转换为byte类型,“大碗转小碗”,但是byte的取值范围为-128~127 10在这个范围当中不会丢失精度
System.out.println(b);
}
}
输出结果为:
10