【面试】深入java包装类

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

在学习包装类时,找了几个比较有意思的类进行了学习!

1.Integer
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[i] = 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(只要范围在-128~127之间的)所指的内存都是一致的,所以打印ok!
(在Java版经常看到很多人对堆与栈搞得很糊涂)


2.  Boolean
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指向同一个堆地址。  

3.这里想说明一下==与equal,很难想像为什么每个博客都介绍这个的区别。
对于对象类型==肯定是栈指针地址的对比,而equal,可以点开String类的源码看一下  
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;   
    }  


4.各个包装类缓存值范围
boolean:true和false
byte:-128~127
char:0~127
short:-128~127
int:-128~127
long:-128~127
特别:对于float和double没有缓存。

在对上述值进行装箱的时候(如:Character c1=127;or
Integer i= Integer.valueOf(1);
这个不行哦:Integer i2=new Integer(1);因为这是新建了一个对象出来。),并不是创建一个新对象而是使用缓存中的对象,,如果超出范围则需要新建立对象。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/liangpei2008/archive/2010/01/30/5272501.aspx

你可能感兴趣的:(java,.net,面试,cache,J#)