数据类型
基本数据类型
类型 | 数据类型 | 大小 | 默认值 | 范围 |
---|---|---|---|---|
整数型 | byte | 1字节 | 0 | -128 ~ 127 |
整数型 | short | 2字节 | 0 | -32768 ~ 32767 |
整数型 | int | 4字节 | 0 | -2147483648 ~ 2147483647 |
整数型 | long | 8字节 | 0L | -9223372036854775808 ~ 9223372036854775807 |
浮点型 | float | 4字节 | 0.0f | 1.4E-45 ~ 3.4028235E+38 |
浮点型 | double | 8字节 | 0.0d | 4.9E-324 ~ 1.7976931348623157E+308 |
布尔型 | char | 2字节 | false | true/false |
字符型 | char | 2字节 | ‘\u0000’ | \u0000 ~ \uFFFF;0 ~ 65535 |
long存不下怎么办? -BigInteger
double存不下了怎么办? -BigDecimal
类型之间的类型转换
-
字母 N 表示无法转换;
-
字母 Y 表示放大转换(widening conversion),由 Java 自动隐式转换;
-
字母 C 表示缩小转换(narrowing conversion),需要显式校正。
-
Y* 表示自动执行的放大转换,但在转换过程中最低有效位可能丢失。
-
布尔值是唯一一种不能和其他基本类型之间相互转换的基本类型
-
有个例外情况是,如果整数字面量(int 类型)的值落在 byte 和 short 类型的取值范围内,就能把这个字面量赋值给 byte 或 short 类型的变量。
基本数据类型转换规则
-
八种基本数据类型,除布尔型之外,其它类型都可以互相转换。
-
小容量转换为大容量,叫做自动类型转换,容量从小到大的排序为:
a. byte < short(char) < int < long < float < double
b. 注意char比short可以表示更大的整数
-
大容量转换为小容量,叫做强制类型转换,需要加强制类型转换符才能编译通过,运行时可能损失精度,也可能不会损失。
-
整数字面量如果没有超出byte short char的取值范围,可以直接赋值给byte short char类型的变量。
-
byte short char混合运算,各自先转换为int再做运算。
-
多种类型混合运算,各自先转换成容量最大的类型,再做运算。
整数型
整数型字面量的四种表现形式
十进制:int a = 10;
二进制:int b = 0b101;
八进制:int o = 012;
十六进制:int d = 0x1F;
💡 当整数字面量没有超出byte的范围
在Java中有这样一个规定,当整数型字面量没有超出byte的范围:可以直接赋值给byte类型的变量。
byte b = 127; // 这是允许的
很显然,这是一种编译优化。同时也是为了方便程序员写代码。
如果超出了范围,例如:
byte b = 128; // 编译报错
这样就会报错,需要做强制类型转换,例如:
byte b = (byte)128;
它的执行结果你知道吗?可以尝试推算一下
在整数类型中,除了byte有这个待遇之外,short同样也是支持的。也就是说:如果整数型字面量没有超出short取值范围时,也是支持直接赋值的。
自动类型转换
-
整数型字面量默认被当做int类型来处理。
-
如果在整数型字面量后面添加 L 或者 l,那么这个整数型字面量就会被当做long类型来处理了(建议L)。
-
java允许小容量的数据直接赋值给大容量的变量。
💡 byte < short < int < long < float < double
- 对于
int a = 10;
这类语句,本身是声明语句和赋值语句的混合- 声明int类型的变量a,给变量a分配4个字节的内存;
- 10为整数型字面量,给10分配int默认类型的4字节存储空间。
- 将字面量10赋值给a这个变量,数据和变量容量相同,则不发生类型转换。
- 考虑:
long d = 2147483647;
的情况?
public class IntTest02{
public static void main(String[] args){
// 100 是4个字节。
// b 是8个字节。
// 小容量可以自动赋值给大容量,叫做自动类型转换。
long b = 100;
// 100L一上来就是分配8个字节。所以这个代码不存在类型转换。
long c = 100L;
// 2147483647 一上来就被当做int来处理,4个字节。
// d是8个字节。存在自动类型转换。
long d = 2147483647;
System.out.println(d);
// 错误: 整数太大(不是long存不下。)
// 原因是:2147483648默认被当做int来处理,分配4个字节。4个字节本身是无法存储2147483648
//long e = 2147483648;
//System.out.println(e);
// 怎么解决?添加一个L。
long e = 2147483648L;
System.out.println(e);
}
}
- 在Java中,多种数据类型混合运算时,各自先转换成容量最大的类型,再做运算
byte a = 100;
int b = 200;
long c = 300L;
long d = a + b + c;
你可以测试一下,如果d变量是int类型则编译器会报错。- byte、short、char混合运算时,各自先转换成int再做运算。
public class DataTypeHomework03{
public static void main(String[] args){
// 通过
short s = 100;
// 报错:大容量不能直接赋值给小容量
s = s - 99;
// 通过
byte b = 100;
// 报错
b = b + 1;
// 通过
char c = 'a';
// 通过
int i = 20;
// 通过
float f = .3F;
// 通过
double d = c + i + f;
// 通过
byte b1 = 11;
// 通过
short s1 = 22;
// 报错
short x = b1 + s1;
}
}
强制类型转换
在 Java 中,如果整数运算超出了指定整数类型的范围,不会上溢或下溢,而是直接回绕
short a = 32767;
short b = 2;
short c = (short)(a+b);
System.out.println(c);
返回结果,c的值为:-32767
💡 编译器的小心思:
以下程序编译通过:
byte x = 10 / 3;
为什么编译通过?这种情况下都是字面量的时候,编译器可以在编译阶段得出结果是3,而3没有超出byte取值范围。可以直接赋值。
以下程序编译报错:
int a = 10;int b = 3;byte x = a / b;
为什么编译失败?这种a和b都是变量的情况下,编译器是无法在编译阶段得出结果的,编译器只能检测到结果是int类型。int类型不能直接赋值给byte类型变量。
怎么解决?要么把x变量声明为int类型,要么强制类型转换,例如:
int a = 10;int b = 3;byte x = (byte)(a / b);
这里需要注意的是:注意小括号的添加,如果不添加小括号,例如:
int a = 10;int b = 3;byte x = (byte)a / b;
这样还是编译报错,因为只是将a强转为byte了,b还是int。byte和int混合运算,结果还是int类型。
浮点型
浮点型数据两种表示形式
第一种形式:十进制
double x = 1.23;
double y = 0.23;
double z = .23;
第二种形式:科学计数法
double x = 0.123E2; // 0.123 * 10的平方
double y = 123.34E-2; // 123.34 / 10的平方
浮点型数据存储原理
符号位:0表示整数。1表示负数。
指数位:比如小数0.123E30,其中30就是指数。表示0.123 * 10的30次幂。所以也有把指数位叫做偏移量的。最大偏移量127。
尾数位:浮点数的小数部分的有效数字。例如:0.00123,那么尾数位存储123对应的二进制。
从浮点型数据存储原理上可以看到,二进制中的指数位决定了数字呈指数级增大。因此float虽然是4个字节,但却可以表示比long更大的数值。因此float容量比long的容量大。
浮点型数据使用注意事项
一旦有浮点型数据参与运算得出的结果,一定不要使用“==”与其它数字进行“相等比较”
不要这样:
double x = 6.9;
double y = 3.0;
double z = x / y;
if(z == 2.3){
System.out.println("相等");
}
可以这样:
double x = 6.9;
double y = 3.0;
double z = x / y;
if(z - 2.3 < 0.000001){
System.out.println("相等");
}
💡浮点型字面量默认被当做double
Java中,浮点型字面量默认被当做double类型,如果要当做float类型,需要在数字后面添加 F 或 f。
// 编译报错:3.0默认被当做double类型,大容量无法直接赋值给小容量。如何修改:
// float f = 3.0;
float f = 3.0F;
另外,可以通过以下程序的输出结果看到,double精度高于float:
//1.5656856894
double d = 1.5656856894;
System.out.println(d);
//1.5656856
float f = 1.5656856894F;
System.out.println(f);
字符型
- 占用两个字节,0~65535(和short容量相同,但char可以取更大的整数)
- 单个字符,使用单引号括起来,不能是多个字符
- 可以保存一个汉字
- 空字符与空格字符是不同的。空字符表示什么也没有。空格字符表示一个空格。
- char c = ‘’; 这是不允许的
- char c = ‘\u0000’; 这表示一个空字符,也是char的默认值。\u0000是一个Unicode码。
转义字符
- \t: 表示制表符,相当于按下 Tab 键
- \n: 表示换行符
- “: 表示双引号(”)
- ‘: 表示单引号(’)
- \: 表示反斜线(\)本身
常见编码方式
💡 字符编码:人为规定的文字与二进制之间的转换关系。
解码(Decoding)和编码(Encoding)是两个常用的概念,分别表示将二进制数据转换为字符和将字符转换为二进制数据。
ASCII 编码(American Standard Code for Information Interchange:美国信息交换标准编码):采用1个字节编码,包括字母、数字、符号和控制字符等。
Latin-1编码(ISO 8859-1),采用1个字节编码。该编码方式是为了表示欧洲语言(如荷兰语、西班牙语、法语、德语等)中的字符而设计的,共支持 256 个字符。
ANSI 编码(American National Standards Institute:美国国家标准协会):采用1个字节编码,支持英文、拉丁文等字符。两个ANSI码可以表示一个汉字。
Unicode 编码:可表示所有语言的字符。采用了十六进制表示,占用 2 个字节或 4 个字节,最多可表示超过一百万个字符。 (使用这种方式是有点浪费空间的,例如英文字符’a’其实采用一个字节存储就够了。
在线Unicode编码转换-Unicode和ASCII在线互转-中文转Unicode工具
UTF-8 编码(Unicode Transformation Format,8-bit):基于 Unicode 编码的可变长度字符编码,能够支持多语言和国际化的需求,使用 1~4 个字节来表示一个字符,是目前 Web 开发中最常用的字符编码方式。 (一个英文字母1个字节,一个汉字3个字节。)
UTF-16 编码:基于 Unicode 编码的可变长度字符编码,使用 2 或 4 个字节来表示一个字符,应用于很多较早的系统和编程语言中。 (一个英文字母2个字节。一个汉字4个字节。)
UTF-32编码:基于Unicode编码的固定长度字符编码,其特点是每个字符占用4个字节。
GB2312 编码(小):是中国国家标准的简体中文字符集,使用 2 个字节来表示一个汉字,是 GBK 编码的前身。
GBK 编码(Guo Biao Ku)(中):是针对中文设计的一个汉字编码方式,使用 2 个字节来表示一个汉字,能够表示中国内地的所有汉字。
GB18030编码(大):是中国国家标准GB 18030-2005《信息技术 中文编码字符集》中规定的字符集编码方案,用于取代GB2312和GBK编码。
Big5 编码(大五码):是台湾地区的繁体中文字符集,使用 2 个字节来表示一个汉字,适用于使用繁体中文的应用场景。
char参与的运算
Java中允许将一个整数赋值给char类型变量,但这个整数会被当做ASCII码值来处理
需要特别注意的是,这个码值有要求,不能超出char的取值范围
只要没有超出byte short char的取值范围,是可以直接赋值给byte short char类型变量的
System.out.println(‘a’ + 1);结果是什么?
char c = ‘a’ + 1;结果是什么?
以下程序结果是什么?
byte b = 1;
short s = 1;
char c = 1;
short num = b + s + c;
byte short char混合运算时,各自会先转换成int再做运算!!!
boolean类型
boolean类型只有两个值:true、false。没有其它值,没有0和1这一说。
通常用于表示一些逻辑上的真假值,并在程序中进行逻辑控制,例如以下代码:
boolean gender = true;
if(gender){
System.out.println("男");
}else{
System.out.println("女");
}
引用数据类型
- 类
- String(不是 基本数据类型)
- Object
- 接口
- 数组
- 枚举