sizeof for java

今天没事看精华区,发现去年有人讨论java的sizeof。结论好想是没什么好办法。
上面的地址先讨论了一下java中没有sizeof的必要,然后给了一段实现sizeof的代码。

In previous issues we've mentioned that Java(tm) has no sizeof() operator
 like C/C++. With uniform sizes for primitive data types, and a different
 style of memory allocation, the need for sizeof() really isn't there. And
 it's hard to define what sizeof() would mean anyway, given that an object
 may not contain other objects, but only references to them. 


But it's interesting to experiment with the 1.1 reflection feature and see
 whether a method can be devised that will return useful information about
 object sizes. 


The Sizeof class below tries to do this, for a passed-in data structure. 
It walks the structure and tallies up the total size in bytes. It ignores
 alignment and packing issues and hidden fields in structures, and assumes
 a boolean is of size 1 and a reference of size 4 (reference sizes may vary
; for example SZ_REF might be 8 on a machine with 64-bit pointers). 


It does not count static data members of class instances, but does include
 members inherited/implemented from superclasses and interfaces. It does 
not follow references in object instances or in arrays, except for the case
 of a multi-dimensional array, where the reference is to another array. 


Included are some tests that illustrate what results are expected in given
 cases. 


        import java.lang.reflect.*;
        
        class test_Class1 {
                private int a1;
                public byte a2;
                protected char a3[];
                static byte a33;
        }
        
        class test_Class2 extends test_Class1 {
                static float a33;
                byte a3;
                short a4;
                double a5[] = new double[10];
        }
        
        class test_Class3 extends test_Class2 {
                boolean a4;
                static int a44;
                char a5;
                long a6;
        }
        
        interface test_Class4 {
                public byte x = 1;
        }
        
        interface test_Class5 extends test_Class4 {
                public int x = 2;
        }
        
        class test_Class6 {
                public double x;
        }
        
        class test_Class7 extends test_Class6 implements test_Class5 {
                char x[] = null;
        }
        
        public class Sizeof {
        
                private static final int SZ_REF = 4;
        
                public static int sizeof(boolean b)
                {
                        return 1;
                }
        
                public static int sizeof(byte b)
                {
                        return 1;
                }
        
                public static int sizeof(char c)
                {
                        return 2;
                }
        
                public static int sizeof(short s)
                {
                        return 2;
                }
        
                public static int sizeof(int i)
                {
                        return 4;
                }
        
                public static int sizeof(long l)
                {
                        return 8;
                }
        
                public static int sizeof(float f)
                {
                        return 4;
                }
        
                public static int sizeof(double d)
                {
                        return 8;
                }
        
                private static int size_inst(Class c)
                {
                        Field flds[] = c.getDeclaredFields();
                        int sz = 0;
        
                        for (int i = 0; i < flds.length; i++) {
                                Field f = flds[i];
                                if (!c.isInterface() &&
                                    (f.getModifiers() & Modifier.STATIC) != 0)
                                        continue;
                                sz += size_prim(f.getType());
                        }
        
                        if (c.getSuperclass() != null)
                                sz += size_inst(c.getSuperclass());
        
                        Class cv[] = c.getInterfaces();
                        for (int i = 0; i < cv.length; i++)
                                sz += size_inst(cv[i]);
        
                        return sz;
                }
        
                private static int size_prim(Class t)
                { 
                        if (t == Boolean.TYPE)
                                return 1;
                        else if (t == Byte.TYPE)
                                return 1;
                        else if (t == Character.TYPE)
                                return 2;
                        else if (t == Short.TYPE)
                                return 2;
                        else if (t == Integer.TYPE)
                                return 4;
                        else if (t == Long.TYPE)
                                return 8;
                        else if (t == Float.TYPE)
                                return 4;
                        else if (t == Double.TYPE)
                                return 8;
                        else if (t == Void.TYPE)
                                return 0;
                        else
                                return SZ_REF;
                }
        
                private static int size_arr(Object obj, Class c)
                {
                        Class ct = c.getComponentType();
                        int len = Array.getLength(obj);
        
                        if (ct.isPrimitive()) {
                                return len * size_prim(ct);
                        }
                        else {
                                int sz = 0;
                                for (int i = 0; i < len; i++) {
                                        sz += SZ_REF;
                                        Object obj2 = Array.get(obj, i);
                                        if (obj2 == null)
                                                continue;
                                        Class c2 = obj2.getClass();
                                        if (!c2.isArray())
                                                continue;
                                        sz += size_arr(obj2, c2);
                                }
                                return sz;
                        }
                }
        
                public static int sizeof(Object obj)
                {
                        if (obj == null)
                                return 0;
        
                        Class c = obj.getClass();
        
                        if (c.isArray())
                                return size_arr(obj, c);
                        else
                                return size_inst(c);
                }
        
                private static void err(String s)
                {
                        System.err.println("*** " + s + " ***");
                }
        
                private static void test()
                {
                        if (sizeof(null) != 0)
                                err("null");
        
                        if (sizeof(true) != 1)
                                err("boolean");
                        if (sizeof((byte)37) != 1)
                                err("byte");
                        if (sizeof('x') != 2)
                                err("char");
                        if (sizeof((short)37) != 2)
                                err("short");
                        if (sizeof(37) != 4)
                                err("int");
                        if (sizeof(37L) != 8)
                                err("long");
                        if (sizeof(37.0f) != 4)
                                err("float");
                        if (sizeof(37.0) != 8)
                                err("double");
        
                        if (sizeof(new boolean[0]) != 0)
                                err("boolean[0]");
                        if (sizeof(new byte[10]) != 10)
                                err("byte[10]"); 
                        if (sizeof(new char[10][10]) != 200 + 10 * SZ_REF)
                                err("char[10][10]");
                        if (sizeof(new short[10][11][12]) != 2640 +
                            120 * SZ_REF)
                                err("short[10][11][12]");
                        if (sizeof(new int[0][10]) != 0)
                                err("int[0][10]");
        
                        if (sizeof(new String[100]) != 100 * SZ_REF)
                                err("String[100]");
                        if (sizeof(new String[10][10]) != 110 * SZ_REF)
                                err("String[10][10]");
        
                        Object ov[] = new Object[3];
                        ov[0] = new byte[10];
                        ov[2] = new double[10];
                        if (sizeof(ov) != 90 + 3 * SZ_REF)
                                err("Object[3]");
        
                        String sv[] = new String[10];
                        for (int i = 0; i < 10; i++)
                                sv[i] = new String();
                        if (sizeof(sv) != 10 * SZ_REF)
                                err("String[10]");
        
                        if (sizeof(new Object()) != 0)
                                err("Object");
                        if (sizeof(new Integer(37)) != 4)
                                err("Integer(37)");
        
                        if (sizeof(new test_Class1()) != 5 + SZ_REF)
                                err("test_Class1");
                        if (sizeof(new test_Class2()) != 8 + 2 * SZ_REF)
                                err("test_Class2");
                        if (sizeof(new test_Class3()) != 19 + 2 * SZ_REF)
                                err("test_Class3");
        
                        if (sizeof(new test_Class7()) != 13 + SZ_REF)
                                err("test_Class7");
                }
        
                public static void main(String args[])
                {
                        test();
                }
        
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值