A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Charay 中级黑马   /  2014-12-25 20:20  /  906 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

java 包装类
一.装箱 拆箱
  Integer a = 3;              这是自动装箱
  int     i = new Integer(2); 这是自动拆箱
  就是基本类型和其对应的包装类型在需要的时候可以互相转换,具体过程由编译器完成
  比如自动装箱:
  Integer a=3;
  其实编译器调用的是static Integer valueOf(int i)这个方法

  valueOf(int i)返回一个表示指定的int 值的Integer 对象
  那么就变成这样: Integer a=3;   =>    Integer a=Integer.valueOf(3);
  对应的  int intValue()  返回该Integer对象的int值,是拆箱

二.包装类
  而在JAVA中,已经将Java的基本数据类型与其提供了一些常用的类型操作的方法进行了封装,这样才有一切皆对象的感觉。

  在学习包装类时,找了几个比较有意思的类进行了学习!
  • Integer
[url=][/url]

Integer i=3;  //上述语句毫无疑问,是进行一个类的创建!但通过Java Decompiler进行反编译后,发现这条语句被编译器优化成了
Integer integer = Integer.valueOf(1);比较有意思,于是就看看valueOf中是什么  
public static Integer valueOf(int i) {      final int offset = 128;      if (i >= -128 && i <= 127) { // must cache           return IntegerCache.cache[i + offset];      }          return new Integer(i);      }  IntegerCache是什么     private static class IntegerCache {      private IntegerCache(){}      static final Integer cache[] = new Integer[-(-128) + 127 + 1];      static {          for(int i = 0; i < cache.length; i++)          cache = new Integer(i - 128);      }      }  原来当创建Integer时,-128-127范围内的数据已经以static final的形式预先创建了,放在堆中。当用户声明该范围的Integer类型的变量时,直接从IntegerCache中读取。  可以做一个试验:      Integer integer=1;      Integer integer2=1;      if (integer==integer2){              System.out.println("ok");      }  结论是:integer与integer2所指的内存都是一致的,所以打印ok!  
  Integer i4 = new Integer(1);
  Integer i5 = new Integer(1);
  if(i4==i5){
    System.out.println("ok");
  }
结论是:不打印ok.

    Integer i4 = new Integer(1);
  Integer i5 = 1;
  if(i4==i5){
    System.out.println("ok");
  }
结论是:不打印 ok

上面有何区别呢?
Integer integer=1;  =>    Integer a=Integer.valueOf(1); 看其源码调用了IntegerCache 缓存。所以地址一样。
Integer i4 = new Integer(1); 是new 出一个对象。

(在Java版经常看到很多人对堆与栈搞得很糊涂)  [url=][/url]


  Integer a= new Integer(1000);  System.out.println(a==1000);
  //输出true.原因是在做==比较时,变量a会做自动拆箱(unbox)操作,把自己变成基本类型。==中有基本类型和包装类时是把包装类拆箱成基本类型。而不是把基本类型装箱成包装类。
  //== 中只要有一个是基本类型那么就为true
2.Boolean

[url=][/url]
Boolean boolean1=true;  //这个代码与上述的Integer integer=1的做法类似,编译器对此进行优化(大家可以下载一个java Decompiler)。优化后的语句为Boolean boolean1 = Boolean.valueOf(true);这时可以看看valueOf的代码   public static Boolean valueOf(boolean b) {          return (b ? TRUE : FALSE);      }   再看看TRUE与FALSE是什么?   public static final Boolean TRUE = new Boolean(true);      public static final Boolean FALSE = new Boolean(false);  原来Boolean在创建时已经创建了二个static final的Boolean对象,True与False。这时做个实验:  Boolean boolean1=true;           Boolean boolean2=true;           if (boolean1==boolean2){               System.out.println("ok");           }  结果:boolean1与boolean2指向同一个堆地址。  这里想说明一下==与equal,很难想像为什么每个博客都介绍这个的区别。对于对象类型==肯定是栈指针地址的对比,而equal,可以点开源码看一下  public boolean equals(Object anObject) {      if (this == anObject) {          return true;      }      if (anObject instanceof String) {          String anotherString = (String)anObject;          int n = count;          if (n == anotherString.count) {          char v1[] = value;          char v2[] = anotherString.value;          int i = offset;          int j = anotherString.offset;          while (n-- != 0) {              if (v1[i++] != v2[j++])              return false;          }          return true;          }      }      return false;      }  [url=][/url]


    包装类都是 final 类型
      Boolean:(全部缓存)
  Byte: (全部缓存)
  Character ( <=127 缓存)
  Short (-128~127 缓存)
  Long (-128~127 缓存)
  Float (没有缓存)
  Doulbe (没有缓存)



1 个回复

倒序浏览
真是醉了,排好的版,怎么一发上去就全乱了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马