包装类

213 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

2.1 包装类

2.1.1 概念

包装类,就是在基本数据类型的基础上,做一层包装。每一个包装类的内部都维护了一个对应的基本数据类型的属性,用来存储管理一个基本数据类型的数据。

包装类是一种引用数据类型,使用包装类,可以使得基本数据类型数据有着引用类型的特征。例如,可以存储在集合中。同时,包装类还添加了若干个特殊的方法。

2.1.2 基本数据类型对应的包装类型

基本数据类型包装类型
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

2.1.3 装箱拆箱

手动装箱/手动拆箱

2.1.4 手动装箱

概念: 由基本数据类型,完成向对应的包装类型进行转换。

方式1:可以通过每一个包装类的构造方法来完成。在每一个包装类的构造方法中,都有一个与之对应的基本数据类型作为参数的重载方法,此时,直接将需要包装起来的基本数据类型,写到构造方法的参数中即可完成装箱。

     /**
      * 完成手动的装箱
      * 由基本数据类型向引用数据类型的转换
      * 通过包装类的构造方法
      */
     public static void boxing() {
         // 1. byte -> Byte
         Byte num1 = new Byte((byte) 10);
         // 2. short -> Short
         Short num2 = new Short((short) 10);
         // 3. int -> Integer
         Integer num3 = new Integer(10);
         // 4. long -> Long
         Long num4 = new Long(10);
         // 5. float -> Float
         Float num5 = new Float(3.14f);
         // 6. double -> Double
         Double num6 = new Double(3.14);
         // 7. char -> Character
         Character num7 = new Character('a');
         // 8. boolean -> Boolean
         Boolean num8 = new Boolean(false);
     }

方法2:可以通过包装类的静态方法 valueOf() 完成装箱。每一个包装类中,都有一个静态方法 valueOf(),这个方法的参数是包装类型对应的基本数据类型的参数。直接将需要包装起来的基本数据类型的数据,写到这个方法的参数中,即可完成对这个基本数据类型的装箱。

     /**
      * 第二种手动装箱 valueOf()
      */
     public static void boxing2(){
         Byte num1 = Byte.valueOf((byte) 10);
         Short num2 = Short.valueOf((short) 10);
         Integer num3 = Integer.valueOf(10);
         Long num4 = Long.valueOf(10L);
         Float num5 = Float.valueOf(3.14F);
         Double num6 = Double.valueOf(3.14);
         Character num7 = Character.valueOf('a');
         Boolean num8 = Boolean.valueOf(true);
     }

2.1.5 手动拆箱

概念:由包装类型,完成向对应的基本数据类型进行转换。

方式:使用每一个包装类型对象的 xxxValue 可以实现。这里的 xxx 就是需要转型的基本数据类型。例如,如果需要转型为int类型,则直接调用intValue 即可。

     /**
      * 完成手动的拆箱
      * 包装类型转基本数据类型
      */
     public static void unboxing() {
         Byte num1 = Byte.valueOf((byte) 10);
         byte n1 = num1.byteValue();
 
         Short num2 = Short.valueOf((short) 10);
         short n2 = num2.shortValue();
 
         Integer num3 = Integer.valueOf(10);
         int n3 = num3.intValue();
 
         Long num4 = Long.valueOf(10L);
         long n4 = num4.longValue();
 
         Float num5 = Float.valueOf(3.14F);
         float n5 = num5.floatValue();
 
         Double num6 = Double.valueOf(3.14);
         double n6 = num6.doubleValue();
 
         Character num7 = Character.valueOf('a');
         char n7 = num7.charValue();
 
         Boolean num8 = Boolean.valueOf(true);
         boolean n8 = num8.booleanValue();
     }

备注:某些包装类对象,除了可以拆箱成对应的基本数据类型的数据之外。还可以将包装起来的数字转成其它的基本数据类型的数据。例如,Integer,除了有 intVlaue 之外,还有 byteValue 等方法。其实,就是将包装起来的int数据,强行转成byte类型返回结果。

2.1.6 自动装箱拆箱

概念:所谓的自动装箱和拆箱,指的是在进行装箱和拆箱的时候,不用再使用上面的方法完成装箱和拆箱的操作。在JDK1.5之后,装箱和拆箱是可以自动完成的!

只需要一个赋值语句。

方式:没有什么特殊的语句,直接去进行赋值即可。

 // 自动装箱:由一个基本数据类型,到对应的包装类型的转换。只需要一个赋值语句即可完成。
 Integer i1 = 10;
 // 自动拆箱:由一个包装类型
 int a = i1;

注意:既然有自动的装箱和拆箱,为什么还要掌握手动的装箱和拆箱。因为,在有些情况下,自动的装箱和拆箱是不能使用的。

示例:如果在一个类的重载方法中,有两个方法的参数类型,一个是基本数据类型,一个是对应的包装类型。此时,将无法使用自动装箱和拆箱。必须通过手动的装箱和拆箱完成对应的方法调用。

 package com.laity.basicSyntax.day7.ePackageClasses;
 
 /**
  * @author : Laity
  * @Project: JavaLaity
  * @Package com.laity.basicSyntax.day7.ePackageClasses
  * @date Date : 2021年12月08日 23:14
  * @Description: 手动装箱和拆箱的使用场景
  */
 public class Boxing2 {
     public static void main(String[] args) {
         test(10);
         // 只能手动装箱
         test(Integer.valueOf(10));
     }
 
     public static void test(int a) {
         System.out.println("test(int a) 方法被调用了");
     }
 
     public static void test(Integer a) {
         System.out.println("test(Integer a) 被调用了");
     }
 }

2.1.7 享元原则

概念:是程序设计的一个基本原则。当我们需要在程序中频繁的用到一些元数据的时候,此时,我们可以提前将这些元数据准备好,当需要的时候,直接拿过来使用即可。使用完成之后,也不进行销毁,以便下次继续使用。

包装类中的享元:将常用到的基本数据类型对应的包装类对象,预先存储起来。当使用到这些基本数据类型对应的包装类对象的时候,可以直接拿过来使用,不用再实例化新的对象了。

示例:Integer 类中,将[ -128, 127]范围内的数字对应的包装类对象预先存到了一个 Integer.cache 数组中,每当我们用到这个范围内的数字的时候,可以直接从这个数组中获取到元素。如果用到了不在这个范围内的数字,再去进行新的包装类对象的实例化。这样,不用频繁的开辟空间、销毁空间,节省CPU资源。

 package com.laity.basicSyntax.day7.ePackageClasses;
 
 /**
  * @author : Laity
  * @Project: JavaLaity
  * @Package com.laity.basicSyntax.day7.ePackageClasses
  * @date Date : 2021年12月08日 23:54
  * @Description: 装箱中的享元原则
  */
 public class Boxing3 {
     public static void main(String[] args) {
         Integer i1 = new Integer(10);
         Integer i2 = new Integer(10);
 
         System.out.println(i1 == i2);       // 比的是地址     false
         System.out.println(i1.equals(i2));  // 比的是value   true
 
         Integer i3 = Integer.valueOf(10);
         Integer i4 = Integer.valueOf(10);
         System.out.println(i3 == i4);   // true
         System.out.println(i3.equals(i4));
 
         Integer i5 = Integer.valueOf(200);
         Integer i6 = Integer.valueOf(200);
         System.out.println(i5 == i6);   // false
     }
 }