1. 基本数据类型的存储大小、取值范围、默认值、包装器类型
基本数据类型 | 存储大小 | 取值范围 | 默认值 | 包装器类型 |
---|---|---|---|---|
byte | 1 个字节 | [-27, -27-1], 即 [-128, 127] | 0 | Byte |
short | 2 个字节 | [-215, 215-1] | 0 | Short |
int | 4 个字节 | [-231, 231-1] | 0 | Integer |
long | 8 个字节 | [-263, 263-1] | 0L | Long |
float | 4 个字节(符合 IEEE 754 标准) | [-3.402823e+38, -1.401298e-45] + [1.401298e-45, 3.402823e+38] | 0.0f | Float |
double | 8 个字节(符合 IEEE 754 标准) | [-1.797693e+308, -4.9000000e-324] + [4.9000000e-324, 1.797693e+308] | 0.0d | Double |
char | 2 个字节 | [Unicode 0, Unicode 216-1] | ‘\u0000’, 即字符’0’ | Character |
boolean | 4 个字节 | true 和 false | false | Boolean |
2. 为什么 Java 中 byte
类型的取值范围为 -128~127
- 本质:计算机是以二进制补码的形式表示数据的
- 参考:为什么 Java 中
byte
类型的取值范围为 -128~127
3. 给 long
类型赋值时有什么需要注意的
- 给
long
类型赋值时,如果常量超出了int
的表示范围-2^31 ~ 2^31 -1
,需要在常量后面加大写字母L
(或小写字母),这是因为整型常量默认是int
类型的 - 很多开发规范里为防止字母
L
的小写和数字 1 混淆,建议使用大写
4. 浮点类型 float
、double
分别占几个字节?赋值时有什么需要注意的
- 分别占 4、8 个字节
- 因为浮点类型默认是
double
类型,所以对于float
类型需要在后面加大写字母F
或小写字母f
5. 布尔类型 boolean
占用几个字节
- 在《Java 虚拟机规范》一书中的描述:“虽然定义了
boolean
这种数据类型,但是只对它提供了非常有限的支持。在 Java 虚拟机中没有任何供boolean
值专用的字节码指令,Java 语言表达式所操作的boolean
值,在编译之后都使用 Java 虚拟机中的int
数据类型来代替,而boolean
数组将会被编码成 Java 虚拟机的byte
数组,每个boolean
元素占 8 位” - 也就是说 JVM 规范指出
boolean
当做int
处理,也就是 4 字节,boolean
数组当做byte
数组处理。这样我们可以得出boolean
类型单独使用是 4 个字节,在数组中是确定的 1 个字节
6. 那虚拟机为什么要用 int
来代替 boolean
呢,为什么不用 byte
或 short
,这样不是更节省内存空间吗
- 使用
int
的原因是,对于当下 32 位的处理器 CPU 来说,一次处理数据是 32 位(这里不是指的是 32/64位系统,而是指 CPU 硬件层面) - 因为 CPU 寻址系统只能 32 位 32 位地寻址,具有高效存取的特点。32 位 CPU 使用 4 个字节是最为节省的,哪怕是 1 个
bit
它也是占用 4 个字节
7. 字符类型占用几个字节,怎么表示
- 字符类型
char
表示一个字符,这个字符可以是中文字符,也可以是英文字符。占用2 个字节,赋值时把常量字符用单引号括起来 - 大部分的常用字符用一个
char
就可以表示,但有的特殊字符用一个char
表示不了。It has a minimum value of ‘\u0000’ (or 0) and a maximum value of ‘\uffff’ (or 65,535 inclusive)(跟 Android 方法数限制的 65535 是巧合吗)
8. 数字类型直接量之间的赋值
- 直接量是在程序中直接出现的常量值。将整数类型的直接量赋值给整数类型的变量时,只要直接量没有超出变量的取值范围,即可直接赋值。如果直接量超出了变量的取值范围,则会导致编译错误
- 整数类型的直接量默认是
int
类型。如果直接量超出了int
类型的取值范围,则必须在其后面加上字母L
或l
,将直接量显性声明为long
类型,否则会导致编译错误 - 浮点类型的直接量默认是
double
类型。如果要将直接量表示成float
类型,则必须在其后面加上字母F
或f
。将double
类型的直接量赋值给float
类型的变量是不允许的,会导致编译错误
9. 基本数据类型之间的转换
数字类型转换
- 不同的数字类型对应不同的范围,按照范围从小到大的顺序依次是:
byte
、short
、int
、long
、float
、double
- 将小范围类型的变量转换为大范围类型称为拓宽类型,不需要显性声明类型转换;将大范围类型的变量转换为小范围类型称为缩窄类型,必须显性声明类型转换,否则会导致编译错误
- 不同的数字类型对应不同的范围,按照范围从小到大的顺序依次是:
字符类型与数字类型之间的转换
- 字符类型与数字类型之间可以进行转换
- 将数字类型转换成字符类型时,只使用整数的低 16 位(因为字符类型占用 2 个字节;浮点数类型将整数部分转换成字符类型)
- 将字符类型转换成数字类型时,字符的统一码转换成指定的数值类型。如果字符的统一码超出了转换成的数值类型的取值范围,则必须显性声明类型转换。
布尔类型不能与其他基本数据类型进行转换
- 布尔类型不能转换成其他基本数据类型,其他基本数据类型也不能转换成布尔类型
10. 局部变量的默认赋值是怎样的
- Local variables are slightly different; the compiler never assigns a default value to an uninitialized local variable. If you cannot initialize your local variable where it is declared, make sure to assign it a value before you attempt to use it. Accessing an uninitialized local variable will result in a compile-time error. – 试图访问一个没有初始化的局部变量会导致编译时错误
- Official Reference: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
11. 新建一个基本类型的数组有哪几种写法
int[] arr = {1, 2, 3};
简单粗暴派(毛)int[] arr = new int[] {1, 2, 3};
左右逢源派(周)int[] arr = new int[3]; arr[0] = 1; arr[1] = 2; arr[2] = 3;
学院教条派(王)
12. int[] arr = new int[3] {1, 2, 3}
这种写法是否正确,为什么
- 不正确
- 可以这么理解,因为初始值已经决定了长度,再指定一个长度,如果不一致,计算机将无所适从(说白了,JVM 还没有那么智能,也许将来新版本会改进这个问题)
13. 数组在内存中的表示形式是怎样的
- 数组在内存中两块内存空间
- 一块用于存储数组内容本身,另一块用于存储数组第一个元素内容在内存中的实际位置
14. 为什么数组要用两块空间,不能只用一块吗
- 为了方便不同长度的数组之间的赋值
- 也就是说,给数组变量赋值和给数组中元素赋值是两回事。给数组中元素赋值是改变数组内容,给数组变量赋值则会让变量在内存中指向一个不同的位置