支持递归引用,唯一不支持的就是不等长数组,不过要支持这个也不难,两个原因不改进它: 1.大部分数组都是等长的。 2.这个东西实在没看出有什么实际应用,这个是主要原因。 需要读者对反射和数组有比较深的认识:
  package treeroot.util; 
import java.lang.reflect.*; import java.util.*; 
/**  * Compute the size of a Runtime object or Primitive type.  * Because the memory allocation is unknown,we just add   * all the fields size of a object.  * the primitive size is thounght as   * boolean:1  * byte:1  * short:2  * char:2  * int:4  * float:4  * long:8  * double:8  * the array size are the sum of all the elements  * the null reference is thought to 4 byte.  * the Object instance has the size 8.  *  */ public class Size  {  final private static int BOOLEAN=1;  final private static int BYTE=1;  final private static int SHORT=2;  final private static int CHAR=2;  final private static int INT=4;  final private static int FLOAT=4;  final private static int LONG=8;  final private static int DOUBLE=8;  final private static int REFERENCE=4;  final private static int OBJECT=8;    private static ThreadLocal objs=new ThreadLocal();  private static void init(Object o){   Map map=new IdentityHashMap();   map.put(o,null);   objs.set(map);  } 
 public static int sizeof(boolean i){   return BOOLEAN;  }  public static int sizeof(byte b){   return BYTE;  }  public static int sizeof(short s){   return SHORT;  }  public static int sizeof(char c){   return CHAR;  }  public static int sizeof(int i){   return INT;  }  public static int sizeof(float f){   return FLOAT;  }  public static int sizeof(long l){   return LONG;  }  public static int sizeof(double d){   return DOUBLE;  }  public static int sizeof(Object o){   init(o);   return sizeof0(o);  }  private static int sizeof0(Object o) {   int size=OBJECT;   //if the object is null   if(o==null) return REFERENCE;      Map map=(Map)objs.get();   Class c=o.getClass(); 
  //if it is array   if(c.isArray()){    int[] dimension=getDimension(o);    int len=dimension.length;                Object obj=o;        int num=1;    for(int j=0;j<len-1;j++) num*=dimension[j];    if(dimension[len-1]==0){     size+=num*REFERENCE;    }    else{     num*=dimension[len-1];     //处理递归     int[] index;            Class type=c;     while(type.isArray()) type=type.getComponentType();      //基本类型的数组     if(type.isPrimitive()){      size+=num*sizeofPrimitive(type);     }     //引用类型数组     else{            for(int k=0;k<num;k++){       index=countToIndex(k,dimension);       Object temp=obj;       for(int m=0;m<len;m++){        temp=Array.get(temp,index[m]);       }       //加入数组中的所有对象                     if(!map.containsKey(temp)){        size+=sizeof0(temp);        map.put(temp,null);       }            }     }    }   }         // all not-static fields   Field[] fs=getFields(o.getClass()); 
  for(int i=0;i<fs.length;i++){        Field f=fs[i];    if(!Modifier.isStatic(f.getModifiers())){ 
    Class type=f.getType();     //if it is primitive     if(type.isPrimitive()){      size+=sizeofPrimitive(type);      }     //recurtive     else{      Object obj=null;      try{       obj=f.get(o);      }      catch(IllegalAccessException e){       //won't be happen       throw new RuntimeException("impossible");      }      if(!map.containsKey(obj)){       size+=sizeof0(obj);       map.put(obj,null);      }     }    }   } 
     return size;  } 
 private static  int[] countToIndex(int count,int[] d){   int[] res=new int[d.length];   int c=count;   int i=1;   while(c>0){      int t=1;    for(int j=i;j<d.length;j++) t*=d[j];    if(t>c) i++;    else{     res[i-1]=c/t;     c=c%t;    }   }   return res;  } 
  private static int sizeofPrimitive(Class c){   if (c==boolean.class){    return BOOLEAN;   }   else if(c==byte.class){    return BYTE;   }   else if(c==char.class){    return CHAR;   }   else if(c==short.class){    return SHORT;   }   else if(c==int.class){    return INT;   }   else if(c==float.class){    return FLOAT;   }   else if(c==long.class){    return LONG;   }   else if(c==double.class){    return DOUBLE;   }   else{    throw new IllegalArgumentException("Thrown by sizeOfPrimitive()");   }  }  private static int[] getDimension(Object obj){   int dimension=0;   Class c=obj.getClass();   while(c.isArray()){    dimension++;    c=c.getComponentType();   }   int[] res=new int[dimension];     Object o=obj;   for(int i=0;i<dimension-1;i++){    res[i]=Array.getLength(o);    o=Array.get(o,0);   }   res[dimension-1]=Array.getLength(o); 
  return res;  }    private static Field[] getFields(Class c){   Class superClass=c.getSuperclass();   Field[] s=null;   if(superClass!=null){    getFields(superClass);   }   Field[] fs=c.getDeclaredFields();      //设置为可访问的   Field.setAccessible(fs,true);    
  //合并   int size=0;   if(s!=null) size+=s.length;   if(fs!=null) size+=fs.length; 
  Field[] result=new Field[size];   int index=0;   if((s!=null)&&(s.length>0)){    System.arraycopy(s,0,result,0,s.length);    index+=s.length;   }   if((fs!=null)&&(fs.length>0)){    System.arraycopy(fs,0,result,index,fs.length);   } 
  return result;  } }
   
 
  |