包装类
- 针对八种基本定义相应的引用类型——包装类
- 有类的特点,就可以调用类中的方法。
-
包装类的分类
基本数据类型 包装类 boolean Boolean char Character byte Byte short Short int Integer long Long float Float double Double
-
包装类和基本数据的转换(装箱和拆箱)
- jdk5 前的是手动装箱和拆箱的方式。(装箱:基本类型 -> 包装类,反之拆箱)
- jdk5 后(含jdk5) 的自动装箱和拆箱方式。
- 自动装箱底层调用的是valueOf方法,比如Integer.valueOf()。
- 其他包装类的用法类似。
public class Integer01 { public static void main(String[] args) { // 演示Integer的装箱和拆箱 // jdk5.0 前是手动装箱和拆箱 //手动装箱 int -> Integer int n1 = 100; Integer integer = new Integer(n1); Integer integer1 = Integer.valueOf(n1); // 手动拆箱 Integer -> int int i = integer.intValue(); //jdk5以后,就可以自动装箱和自动拆箱 int n2 = 200; //自动装箱 int -> Integer Integer integer2 = n2;//在底层依旧使用的是Integer.valueOf(n2)方法,这个方法,只是优化了语法 //自动拆箱 Integer -> int int n3 = integer2;//在底层依旧使用的是intValue()方法。 } }
-
包装类型和String类型的相互转换
public class WrapperVSString { public static void main(String[] args) { //包装类 -> String Integer i = 100;//自动装箱 //方式(1) String str = i + ""; //方式(2) String str1 = i.toString(); //方式(3) String str3 = String.valueOf(i);//底层用的还是toString方法 //String -> 包装类(Integer) String str4 = "1234"; //方式(1): Integer i2 = Integer.parseInt(str4);//有使用到自动装箱,以下两个方法实质都是利用者方式1 //方式(2): Integer i1 = Integer.valueOf(str4); //Integer.valueOf(str4) 中 valueOf方法的源码: //public static Integer valueOf(String s) throws NumberFormatException { // return Integer.valueOf(parseInt(s, 10)); // } //方式(3): Integer i3 = new Integer(str4); //new Integer(str4) 中 这个构造方法源码: //public Integer(String s) throws NumberFormatException { // this.value = parseInt(s, 10); // } } }
-
Integer创建机制
Integer类内部有一个静态内部类IntegerCache,内部有静态成员储存了-128到127的Integer数组。
当利用valueOf方法创建Integer类对象时,而值又在[-128,127]范围内时它就会返回这个数组中值对应的对象。
//IntegerCache源码 private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }
//valueOf方法 public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
预先就创建好了共256个Integer对象供后续使用。整个IntegerCache类中的代码均被static修饰,目的是确保在被实际使用时就已经完成了初始化,IntegerCache类中使用cache[]数组缓存了从-128~127供256个Integer对象。
回到valueOf方法,可见,如果传入的int值在cache缓存-128~127的范围中,则直接返回预先创建好的对象,如果不在范围中,则创建一个新的Integer对象返回。
//案例 public void method1(){ Integer i new Integer(1); Integer j new Integer(1); System.out.printin(i==j)://False //所以,这里主要是看范围-128~127就是直接返回 Integer m=1;//底层Integer.valueOf(1);->阅读源码 Integer n=1;//底层Integer.valueOf(1)i System.out.printin(m == n); //T //所以,这里主要是看范围-128~127就是直接返回 //,否则,就new Integer(xx); Integer x = 128;//底层Integer.valueOf(1): Integer y = 128;//底层Integer..valueOf(1): System.out.printin(x == y)//False }