一、基本数据类型
Java 提供了八种基本数据类型,它们用于存储简单的数据值。基本数据类型是值类型,数据直接存储在变量中。每一种基本数据类型都有固定的内存大小和明确的数据范围。
1. 整型(Integer Types)
数据类型 | 位数 | 默认值 | 范围 |
---|---|---|---|
byte | 8位 | 0 | -128 到 127 |
short | 16位 | 0 | -32,768 到 32,767 |
int | 32位 | 0 | -2^31 到 2^31 – 1 |
long | 64位 | 0L | -2^63 到 2^63 – 1 |
2. 浮点型(Floating-Point Types)
数据类型 | 位数 | 默认值 | 范围 |
---|---|---|---|
float | 32位 | 0.0f | 1.4E-45 到 3.4E+38 |
double | 64位 | 0.0d | 4.9E-324 到 1.7E+308 |
3. 字符型(Character Type)
数据类型 | 位数 | 默认值 | 范围 |
---|---|---|---|
char | 16位 | ‘\u0000’ | 0 到 65,535 |
4. 布尔型(Boolean Type)
数据类型 | 位数 | 默认值 | 范围 |
---|---|---|---|
boolean | 1位 | false | true/false |
5. 基本数据类型的特性
- 内存存储:基本数据类型直接存储在栈内存中,且具有固定大小,因此它们的访问速度非常快。
- 不可变性:这些数据类型是不可变的,一旦赋值后,其值就不会随外界的变化而改变。
- 默认值:当声明一个基本数据类型变量而不赋初值时,系统会自动为其分配一个默认值。
二、引用数据类型
引用数据类型 是指那些指向对象的引用,包括类、接口、数组和枚举等。它们存储在堆内存中,变量存储的是对象的内存地址。
1. 类(Class)
类是引用数据类型的一个重要组成部分。通过类可以创建对象,类的实例化是 Java 编程中的核心操作之一。例如:
java复制代码Person person = new Person();
这里,person
是一个引用变量,它保存的是对象 Person
在内存中的地址。
2. 接口(Interface)
接口是另一个引用数据类型,用于定义方法的集合。实现接口的类必须提供接口中的方法实现。
java复制代码public interface Animal {
void speak();
}
3. 数组(Array)
数组是引用类型,虽然它的元素可以是基本数据类型,但数组本身是一个对象。创建数组时,系统会为数组对象在堆内存中分配空间。
java复制代码int[] numbers = new int[5];
4. 字符串(String)
String
是一个特殊的引用数据类型,虽然看起来像基本类型,但它实际上是一个类。字符串是不可变的,即字符串的值一旦创建,就不能被修改。
java复制代码String str = "Hello, World!";
5. 引用数据类型的特性
- 内存存储:引用类型的变量存储在栈内存中,而其引用的对象存储在堆内存中。
- 可变性:引用类型的对象可以改变,引用变量可以指向不同的对象。
- 默认值:引用数据类型的默认值为
null
,表示变量未引用任何对象。
三、基本数据类型与引用类型的区别
特性 | 基本数据类型 | 引用数据类型 |
---|---|---|
存储位置 | 栈内存 | 栈内存和堆内存 |
默认值 | 0(数值型),false(布尔型) | null |
可变性 | 不可变 | 对象内容可变 |
内存大小 | 固定 | 不固定,取决于对象大小 |
性能 | 高效,因直接存储在栈内存中 | 较慢,因需要通过引用访问堆内存 |
四、形参和实参的问题:
在 Java 中,包装类(Wrapper Classes) 是对基本数据类型的封装,用于将基本数据类型转换为对象。由于 Java 的泛型(Generics)不支持基本数据类型,而许多集合框架(如 ArrayList
、HashMap
等)需要操作对象,所以包装类就显得特别重要。
每个基本数据类型都有一个对应的包装类:
基本数据类型 | 对应的包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
一、包装类的作用
- 与集合类一起使用 由于集合类(如
ArrayList
、HashMap
)只能操作对象而不能操作基本数据类型,因此包装类使得基本数据类型能够与这些集合类兼容。java复制代码ArrayList<Integer> list = new ArrayList<>(); list.add(10); // 自动装箱
- 提供额外的方法 包装类提供了许多实用的方法。例如,
Integer
类提供了将字符串转换为整数的parseInt()
方法。java复制代码int number = Integer.parseInt("100");
- 支持类型转换 包装类可以方便地进行类型转换,例如将字符串转为相应的基本类型,或将基本类型的值转为字符串。java复制代码
String str = Integer.toString(123);
二、自动装箱与拆箱
自动装箱(Autoboxing) 是指 Java 编译器在需要时,自动将基本数据类型转换为其对应的包装类对象。拆箱(Unboxing) 则是将包装类对象自动转换为基本数据类型。自动装箱和拆箱让基本类型和包装类之间的转换更加直观和简单。
1. 自动装箱
当我们将一个基本数据类型赋值给包装类时,Java 编译器会自动完成类型转换,这就是自动装箱。
java复制代码int num = 10;
Integer obj = num; // 自动装箱
在这段代码中,int
类型的变量 num
被自动转换为 Integer
对象。
2. 拆箱
当我们将一个包装类对象赋值给基本数据类型时,Java 编译器会自动完成对象到基本类型的转换,这就是拆箱。
java复制代码Integer obj = new Integer(100);
int num = obj; // 拆箱
在这段代码中,Integer
对象 obj
被自动转换为 int
类型的变量 num
。
三、包装类的常用方法
每个包装类都提供了许多用于处理基本数据类型的静态方法和实例方法。以下是一些常用的方法:
1. parseXXX()
和 valueOf()
方法
parseXXX(String s)
:将字符串转换为对应的基本类型。valueOf(String s)
:将字符串转换为包装类对象。
java复制代码int num = Integer.parseInt("123"); // 转换为基本类型
Integer obj = Integer.valueOf("123"); // 转换为包装类对象
2. xxxValue()
方法
包装类提供了将对象转换为基本类型的方法。例如,Integer
类的 intValue()
方法可以将 Integer
对象转换为 int
类型。
java复制代码Integer obj = new Integer(50);
int num = obj.intValue();
3. 比较和转换方法
compareTo()
:用于比较两个包装类对象的大小。toString()
:将包装类对象转换为字符串。
java复制代码Integer num1 = 100;
Integer num2 = 200;
int result = num1.compareTo(num2); // 返回负数,因为 num1 小于 num2
四、包装类的不可变性
与字符串(String
)类似,所有的包装类对象都是不可变的。一旦包装类对象被创建,它的值就不能被更改。如果需要改变值,则必须创建一个新的对象。例如:
java复制代码Integer num = 10;
num = 20; // 实际上是创建了一个新的 Integer 对象
每次改变包装类的值,实际上是创建了一个新的对象,旧的对象会被垃圾回收机制处理掉。
五、包装类的使用场景
缓存机制 Java 中部分包装类(如 Integer
、Byte
、Short
)对某些范围内的值进行了缓存,以提高性能。例如,Integer
缓存了 -128 到 127 之间的整数对象。当你创建一个 Integer
对象且值在这个范围内时,不会创建新的对象,而是从缓存中返回已有的对象。java复制代码Integer a = 127; Integer b = 127; System.out.println(a == b); // 输出 true
泛型与集合框架 在 Java 的集合类中,如 ArrayList
、HashSet
等,不能直接存储基本数据类型,必须使用包装类。例如:java复制代码ArrayList<Double> list = new ArrayList<>(); list.add(3.14); // 自动装箱,将 double 转为 Double
在多线程环境中使用 当需要将基