欢迎光临散文网 会员登陆 & 注册

java包装类的自动封装、自动拆箱和缓存

2022-07-12 17:28 作者:虚云幻仙  | 我要投稿

/**
* 包装类的自动封装、自动拆箱和缓存
*/

public class TestWrapper2 {
   public static void main(String[] args) {
       Integer i1 = 1;
       //自动封装 通过编译器编译后转变为 Integer i1 = Integer.valueOf(1); 供虚拟机执行
       //Integer i1 引用类型变量

       int i2 = i1;
       //自动拆箱 通过编译器编译后转变为 int i2 = i1.intValue(); 供虚拟机执行
       //int i2 基本数据类型

       Integer i3 = null;
       i2 = i3;
       //运行时报错NullPointerException 在虚拟机运行时代码已经变为 i2 = i3.intValue() 但i3为null空指针 没有指向对象就找不到.intValue()方法

       Integer i4 = 4000;
       Integer i5 = 4000;
       System.out.println(i4==i5);
       //结果false i4 = Integer.valueOf(4000) Integer静态方法.valueOf()执行后会new一个新的对象给i4 value值为4000
       //i5 = Integer.valueOf(4000) 同样会new一个新的对象给i5  i4和i5分别指向两个对象

       System.out.println(i4.equals(i5));
       //结果true Integer重写的equals()方法 在判断i5 instanceof Integer 判断i5是Integer的实例后比较i4和i5的value 两个value都是4000所以true
       Integer i6 = 123;
       Integer i7 = 123;
       System.out.println(i6==i7);
       //结果true 原因:在Integer初始化时缓存了整数范围在[-128,127]之间的包装类对象
       //当i6 = Integer.valueOf(123)时 方法没有new新的包装类对象 而是将缓存中提前创建好的value=123的对象返回给i6
       //i7 = 123同理  i6和i7指向的是同一个对象

       /*
           public static Integer valueOf(int i) {
           //静态方法valueOf() 返回Integer类对象
               if (i >= IntegerCache.low && i <= IntegerCache.high)
               //IntegerCache整数缓存 .low=-128 .high=127 系统运行时已经提前建好了-128到127的整数的包装类放到了缓存数组中
                   return IntegerCache.cache[i + (-IntegerCache.low)];
                   //当判断i在-128到127之间 返回对应的对象
               return new Integer(i);
               //当i不在缓存数组的范围内是new对象返回
        */


   }
}

class ImitateInteger {
   //imitate模仿Integer缓存数组
   private int value;
   //每个对象对应一个value值
   private ImitateInteger(int i){
       //将构造器私有 外部生成对象时需要通过.valueOf()方法
       this.value = i;
   }
   private static final int LOW = -128;
   //模拟[-128,127] 两个值设为final常量 private仅方法内判断时调用 static这个属性不需要给对象
   private static final int HIGH = 127;
   private static final ImitateInteger[] cache = new ImitateInteger[HIGH-LOW+1];
   //创建一个数组准备缓存[-128,127]之间的对象 -128到-1是128个 1到127是127个 再加一个0 [127-(-128)+1]
   //换一种想法 从HIGH到LOW总共有HIGH-LOW个数 包含HIGH没包含LOW 所以再+1

   static {
       //静态初始化块 在类加载时执行
       for (int i=LOW;i<=HIGH;i++){
           cache[i+(-LOW)] = new ImitateInteger(i);
           //数组的index范围[0]-[255] i=LOW i-LOW=0  i=HIGH i-LOW=255
           //将value=-128的对象交给cache[0]   value=127的对象交给cache[255]
           //在类加载时即缓存new了-128到127

       }
   }

   public static ImitateInteger valueOf(int i){
       //public供外部调用的代替私有构造器的方法 代替构造器所以返回ImitateInteger对象
       if (i>=LOW&&i<=HIGH){
           //判断i是否在[-128,127]区间
           return cache[i+(-LOW)];
           //对应静态初始化快中的缓存数组 i对应的对象的index要加128即(-LOW)
       }
       return new ImitateInteger(i);
       //不在区间内则new新对象返回
   }

   public static void main(String[] args) {
       ImitateInteger i1 = ImitateInteger.valueOf(1);
       ImitateInteger i2 = ImitateInteger.valueOf(1);
       System.out.println(i1==i2);
       //结果true i1和i2都没有new对象 返回了cache[1+(-(-128))]即cache[129]  cache[129].value对应1

       ImitateInteger i3 = ImitateInteger.valueOf(200);
       ImitateInteger i4 = ImitateInteger.valueOf(200);
       System.out.println(i3==i4);
       //结果false i3和i4分别指向new新生成的对象
   }

   public boolean equals(Object o){
       //重写继承自Object 的equals()
       if (o instanceof ImitateInteger){
           return this.value==((ImitateInteger)o).value;
           //比较两个对象的value  将o强转为ImitateInteger
       }
       return false;
       //不是同类返回false
       // this.equals(o); 用来比较两个对象所以不是static方法

   }

   public int intValue(){
       return this.value;
       //int a = i4.intValue(); 将包装类转为基本数据类型 要转换的是对象 所以不用static
   }

   @Override
   public String toString() {
       //重写toString
       return ""+this.value;
       //返回值只能是字符串
   }
}

java包装类的自动封装、自动拆箱和缓存的评论 (共 条)

分享到微博请遵守国家法律