Java中包装类的学习

包装类


什么是包装类

java中的数据类型int,double等不是对象,无法通过向上转型获取到Object提供的方法,而像String却可以,只因为String是一个对象而不是一个类型。基本数据类型由于这样的特性,导致无法参与转型,泛型,反射等过程。为了弥补这个缺陷,java提供了包装类。

包装类顾名思义就是将基本的数据类型以及一些辅助方法包装到类中,例如自己实现一个int的包装类:

复制代码
class IntDemo {
    private int num;
    public IntDemo(int num) {
        this.num = num;
    }
    public int intValue() {
        return this.num;
    }
}

包装类的特点

Java中的包装类(Wrapper Classes)是Java基本数据类型(primitive types)的类封装形式。Java为每种基本数据类型都提供了对应的包装类,这使得基本数据类型可以被视为对象,从而可以使用面向对象的特性(如继承、多态、方法等)。以下是Java包装类的一些主要特点:

  1. 自动装箱(Autoboxing)和拆箱(Unboxing)

    • 自动装箱:Java SE 5.0(JDK 1.5)引入了自动装箱机制,允许将基本数据类型自动转换为对应的包装类对象。例如,int 可以自动转换为 Integer
    • 自动拆箱:与自动装箱相反,拆箱是将包装类对象自动转换为基本数据类型。例如,Integer 可以自动转换为 int
  2. 提供了更多的功能

    • 包装类提供了一系列实用的方法,如类型转换、比较等。这些基本数据类型本身不具备的方法,通过包装类可以实现。
    • 例如,Integer 类提供了 parseInt(String s) 方法,用于将字符串转换为整数。
  3. null值

    • 包装类对象可以为 null,而基本数据类型不可以。这为程序设计提供了更多的灵活性和控制。
  4. 适用于集合类

    • 由于集合类(如 ListSet)只能存储对象,因此包装类使得基本数据类型可以被存储在集合中。
  5. 缓存机制

    • 某些包装类(如 IntegerBooleanByteShortCharacter 等)在自动装箱时,对于特定范围内的值,会利用缓存机制来重用已有的对象,而不是每次都创建新的对象。这有助于提高性能并减少内存占用。
  6. 类型安全

    • 使用包装类可以提高类型安全性,因为你可以通过泛型(Generics)来限制集合中元素的类型。例如,你可以创建一个只能存储 Integer 对象的 List<Integer>,而不能添加其他类型的对象。
  7. 支持泛型

    • 由于包装类是对象,因此它们可以作为泛型类型参数。这使得可以在集合中存储特定类型的对象,同时保持类型安全。
  8. 提升代码可读性

    • 在某些情况下,使用包装类可以使代码更加清晰易懂。例如,在命名变量时,使用 Integer 而不是 int 可以更明确地表达该变量是一个对象,而不仅仅是一个简单的数值。

综上所述,Java包装类为基本数据类型提供了面向对象的封装,增强了它们的功能和灵活性,使得Java程序更加健壮、灵活和易于维护。

基本数据类型和包装类

在Java中,基本数据类型(Primitive Types)和包装类(Wrapper Classes)是紧密相关的两个概念,但它们之间存在一些关键的区别和联系。

基本数据类型

基本数据类型是Java中最基本的数据类型,它们不是对象,而是直接存储数据值。Java提供了8种基本数据类型,分别是:

  • byte:8位,用于表示非常小的整数。
  • short:16位,用于表示较小的整数。
  • int:32位,用于表示整数(默认)。
  • long:64位,用于表示较大的整数。
  • float:32位,用于表示单精度浮点数。
  • double:64位,用于表示双精度浮点数(默认)。
  • char:16位,用于表示单个Unicode字符。
  • boolean:表示逻辑值,即truefalse

基本数据类型直接存储数据值,因此它们比对象更高效,因为它们不需要额外的内存来存储对象元数据(如类型信息、哈希码等)。但是,由于它们不是对象,因此它们不能使用对象的方法,也不能被放入只能存储对象的集合中(如ListSet)。

包装类

包装类是Java为每种基本数据类型提供的类封装形式。这些类都是java.lang包的一部分,并且都是Object类的子类。包装类允许基本数据类型被视为对象,从而可以使用面向对象的特性。Java提供了以下包装类:

  • Byte:对应byte
  • Short:对应short
  • Integer:对应int
  • Long:对应long
  • Float:对应float
  • Double:对应double
  • Character:对应char
  • Boolean:对应boolean

包装类提供了许多有用的方法,如类型转换、比较、解析字符串等。此外,由于它们是对象,因此它们可以被放入集合中,也可以被序列化和反序列化。

区别和联系

  • 区别

    • 基本数据类型直接存储数据值,而包装类则是对这些值的对象封装。
    • 基本数据类型不是对象,因此它们没有方法,而包装类则提供了许多有用的方法。
    • 基本数据类型不能作为集合的元素,而包装类可以。
    • 基本数据类型在内存和性能上比包装类更高效。
  • 联系

    • Java提供了自动装箱和拆箱机制,允许在基本数据类型和包装类之间自动转换。
    • 包装类是对基本数据类型的扩展,提供了更多的功能和灵活性。
    • 在某些情况下,包装类比基本数据类型更适用,例如在需要对象行为或需要将数据存储在集合中时。

总之,基本数据类型和包装类在Java中都扮演着重要的角色,它们各有优缺点,并且相互补充。在编写Java程序时,应根据具体需求选择使用基本数据类型还是包装类。

包装类的共同特点

自动拆箱/装箱

装箱:

将基本数据类型封装为包装类对象,利用每一个包装类提供的构造方法实现装箱操作。

拆箱:

将包装类中包装的基本数据类型数据取出。

复制代码
// 装箱
Integer integer1 = new Integer(1);
// 拆箱
int integer2 = integer1.intValue(); 

JDK1.5之后提供自动拆装箱。

复制代码
// 自动装箱
Integer integer1 = 1;
// 自动拆箱
int integer2 = integer1; 

自动装箱的内存复用
 自动装箱时,对于Integer var = ?,如果var指向的对象在-128 至 127 范围内的赋值时,生成的Integer实例化对象是由 IntegerCache.cache() 方法产生,它会复用已有对象。和String的共享池操作是一个道理,cache()方法会将位于-128~127范围内产生的Integer对象入池,下次使用的时候,从池中拿去,就不会在创建了。

所以,在这个数值区间内的 Integer对象的栈指向(属性名) 可以直接使用==进行判断,因为值相同,指向的就是同一片区域。但是这个区间之外的所有数据,自动装箱都会在堆上产生实例化,并不再复用已有对象,这是一个大坑,为了避免这个问题,推荐使用 equals 方法进行Integer的判断。

对于所有数值型的包装类来说,都会涉及到上面这种问题,一定要多加注意。

而对于手动装箱,即采用new进行包装类创建时,不会发生内存复用,因为new关键字每次使用,都会开辟新的空间,这和String采用构造方法创建字符串不入池相对应。

posted @   BingBing爱化学-04044  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示