Skip to content

Java 数据类型

数据类型分类

Java 中的数据类型可分为 2 种:

  1. 基本数据类型。

基本数据类型是 Java 语言操作数据的基础,包括 boolean、char、byte、short、int、long、float 和 double,共 8 种。

  1. 引用数据类型。

除了基本数据类型以外的类型,都是所谓的引用类型。常见的有数组(对,没错,数组是引用类型)、class(也就是类),以及接口(指向的是实现接口的类的对象)。

八种基本数据类型

TIP

基本数据类型被创建时,在栈内存中会被划分出一定的内存,并将数值存储在该内存中。

Java 基本类型都有对应的包装类型,基本类型与其对应的包装类型之间的赋值使用自动装箱(转为包装类)与拆箱(转为基本类型)完成。

数据类型长度 (位)数值范围默认值缓存池
boolean1 位false/truefalsefalse 和 true
char16 位'\u0000'(0)到 '\uffff'(65535)\u0000(空格)\u0000 到 \u007F
byte8 位-2^7(-128)到 2^7-1(127)0所有字符
short16 位-2^15(-32768)到 2^15-1(32767)0-128 到 127
int32 位-2^31 到 2^31-10-128 到 127
long64 位-2^63 到 2^63-10-
float32 位-2^128 到 2^1280.0f-
double64 位-2^1024 到 2^10240.0d-

引用数据类型

TIP

引用数据类型被创建时,首先会在栈内存中分配一块空间,然后在堆内存中也会分配一块具体的空间用来存储数据的具体信息,即 hash 值,然后由栈中引用指向堆中的对象地址。

Java 中的类、接口和数组都是引用数据类型。

两种类型的区别

基本数据类型:

  1. 变量名指向具体的数值。
  2. 基本数据类型存储在上。

引用数据类型:

  1. 变量名指向的是存储对象的内存地址,在上。
  2. 内存地址指向的对象存储在上。

是在程序运行时在内存中申请的空间(可理解为动态的过程);切记,不是在编译时;因此,Java 中的对象就放在这里,这样做的好处就是:

当需要一个对象时,只需要通过 new 关键字写一行代码即可,当执行这行代码时,会自动在内存的“堆”区分配空间——这样就很灵活。

,能够和处理器(CPU,也就是脑子)直接关联,因此访问速度更快。既然访问速度快,要好好利用啊!Java 就把对象的引用放在栈里。为什么呢?因为引用的使用频率高吗?

不是的,因为 Java 在编译程序时,必须明确的知道存储在栈里的东西的生命周期,否则就没法释放旧的内存来开辟新的内存空间存放引用——空间就那么大,前浪要把后浪拍死在沙滩上啊。

数据类型转换

自动类型转换

如果以下 2 个条件都满足,那么将一种类型的数据赋给另外一种类型的变量的时候,将会发生自动类型转换(automatic type conversion)。

  • 两种数据类型彼此兼容
  • 目标类型的取值范围大于源数据类型(低级类型数据转换成高级类型数据)
    • 数值型数据的转换:byte→short→int→long→float→double。
    • 字符型转换为整型:char→int。

强制类型转换

所以当两种数据类型不兼容,或目标类型的取值范围小于源类型时,自动转换将无法进行,这时就需要进行强制类型转换。

其语法格式如下:

(type)variableName
(type)variableName

例如:

java
int a = 3;
double b = 5.0;
a = (int)b;
int a = 3;
double b = 5.0;
a = (int)b;

上述代码中首先将 double 类型变量 b 的值强制转换成 int 类型,然后将值赋给 a,但是变量 b 本身的值是没有发生变化的。

在强制类型转换中,如果是将浮点类型的值转换为整数,直接去掉小数点后边的所有数字;而如果是整数类型强制转换为浮点类型时,将在小数点后面补零。

int 和 char 类型互转

这里整理一波 int 和 char 类型的互转,它们之间比较特殊。也会在以后的学习当中经常遇到。

  1. int 类型的数据可以通过 (char) 类型强制、Character.forDigit() 方法和 Integer 的 toString() 方法,转换为 char 类型,其转换的映射可通过 ASCII 表查询。
Java
int a = 65;
System.out.println((char)a); // A
int a = 65;
System.out.println((char)a); // A
  1. char 转 int
java
int a = 'A'; // 65
int a = 'A'; // 65

int[]List<Integer> 转换

在实际开发中,常常会用到 int[]List<Integer> 的相互转换。

  • List<Integer>int[]
java
int[] arr = list.stream().mapToInt(x -> x).toArray();
int[] arr = list.stream().mapToInt(x -> x).toArray();
  • int[]List<Integer>
java
List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList());
List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList());

Java 数组

数组是一个对象,它包含了一组固定数量的元素,并且这些元素的类型是相同的。

数组会按照索引的方式将元素放在指定的位置上,意味着我们可以通过索引来访问这些元素。

在 Java 中,索引是从 0 开始的。

为什么数组的索引从 0 开始?

Java 是基于 C/C++ 语言实现的,而 C 语言的下标是从 0 开始的,所以 Java 就继承了这个良好的传统习惯。

C 语言有一个很重要概念,叫做指针,它实际上是一个偏移量,距离开始位置的偏移量,第一个元素就在开始的位置,它的偏移量就为 0,所以索引就为 0。

数组操作

数组元素的类型可以是基本数据类型(比如说 int、double),也可以是引用数据类型(比如说 String),包括自定义类型。

数组的声明方式:

java
// 方式一(常用)
int[] arr;
// 方式二
int arr[];
// 方式一(常用)
int[] arr;
// 方式二
int arr[];

数组的初始化:

java
// 方式一:指定数组长度
int[] anArray = new int[10];

// 方式二:直接初始化数组中的元素
int anOtherArray[] = new int[] {1, 2, 3, 4, 5};
// 方式一:指定数组长度
int[] anArray = new int[10];

// 方式二:直接初始化数组中的元素
int anOtherArray[] = new int[] {1, 2, 3, 4, 5};

通过方式一创建的数组,数组中的每个元素都会被初始化为默认值,int 类型的就为 0,Object 类型的就为 null。

数组的访问

数组通过指定索引访问对应位置上的元素,如果索引超出数组的界限,就会抛出 ArrayIndexOutOfBoundException

java
int anOtherArray[] = new int[] {1, 2, 3, 4, 5};
for (int i = 0; i < anOtherArray.length; i++) {
    System.out.println(anOtherArray[i]);
}
int anOtherArray[] = new int[] {1, 2, 3, 4, 5};
for (int i = 0; i < anOtherArray.length; i++) {
    System.out.println(anOtherArray[i]);
}

数组的赋值

数组通过数组索引加 = 为数组相应位置的元素赋值:

java
// 赋值 anArray 数组的第一个元素为 10
anArray[0] = 10;
// 赋值 anArray 数组的第一个元素为 10
anArray[0] = 10;

可变数组

在 Java 中,可以使用可变参数用于将任意数量的参数传递给方法,例如:

java
public void test(String... args) {
  //...
}
public void test(String... args) {
  //...
}

参考资料