Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有没有直接的方法来计算基本字段的大小?_Java_Serialization_Reflection_Primitive Types - Fatal编程技术网

Java 有没有直接的方法来计算基本字段的大小?

Java 有没有直接的方法来计算基本字段的大小?,java,serialization,reflection,primitive-types,Java,Serialization,Reflection,Primitive Types,我正在编写一个小型序列化实用程序,我想计算将对象写入字节数组需要保留多少字节。 假设我有一个类,其中有几个字段/getter,比如 int age; String name; Colour colour; boolean active; ... 我想我可以使用反射来迭代字段,看看它们有多大,但我所能做的就是检查它们是否是原始的。这是一个开始,因为我会用一个短的作为对象的偏移。好的,我可以用 if(field.getType() == int.class) { size = Intege

我正在编写一个小型序列化实用程序,我想计算将对象写入字节数组需要保留多少字节。 假设我有一个类,其中有几个字段/getter,比如

int age;
String name;
Colour colour;
boolean active;
...
我想我可以使用反射来迭代字段,看看它们有多大,但我所能做的就是检查它们是否是原始的。这是一个开始,因为我会用一个短的作为对象的偏移。好的,我可以用

if(field.getType() == int.class) {
    size = Integer.BYTES;
}
或者使用地图。这并不难,因为我只需要知道原语的大小。但出于好奇:有没有直接的方法

编辑以澄清: 我使用它来序列化数据,基本上类似于DataOutput/InputStream,但有一些我自己想要的调整

API类如下所示:

public final void write(int i) {
    checkBounds(Integer.BYTES);
    PrimitiveWriteUtil.write(i, data, marker);
    advance(Integer.BYTES);
}
实际工作由实用程序类完成:

public static void write(int i, byte[] target, int pos) {
    target[pos] =       (byte) ((i >>> 24) & 0xFF);
    target[pos + 1] =   (byte) ((i >>> 16) & 0xFF);
    target[pos + 2] =   (byte) ((i >>>  8) & 0xFF);
    target[pos + 3] =   (byte) ((i >>>  0) & 0xFF);
}

因此,我想知道字节数组所需的大小,这样我就可以避免以后检查和调整大小的工作。

原语的大小是


byte
是1字节,
short
char
是2字节,
int
float
是32字节,
double
long
是64字节。

如果你需要将其用于任何目的而不仅仅是理论练习,依赖精确的数字可能是危险的

由于您想使用它来分配字节数组的序列化大小,请考虑使用BytErayOutPutsStudio.< /P>

ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bytesOut);

out.writeObject(new MyObject(12, "JackDaniels", true));
out.close();
System.out.println("Number of bytes for serialized object: " + bytesOut.toByteArray().length);
MyObject助手类的完整工作代码位于

这并不能直接回答你的问题,但我相信这是实现你的目标的正确途径



您可以通过实现readObject和writeObject方法来修改序列化的方式。例如,看一看。

好吧,您已经知道了
字节
字段,问题是,这些字段在相应的包装器类型中声明,并且没有简单的方法获取基本类型的包装器类型。就代码大小而言,获取它的最简单方法是通过
get
方法读取字段,这意味着包装原语值:

public class FieldSize {
    static final int BOOLEAN_SIZE = 1; // adjust to your storage method
    static final int REF_SIZE = 2;     // dito
    private static int getSize(Field f, Object o) {
        try {
        return f.getType().isPrimitive()? f.getType()==boolean.class? BOOLEAN_SIZE:
               f.get(o).getClass().getField("BYTES").getInt(null): REF_SIZE;
        } catch(ReflectiveOperationException ex) {
            throw new AssertionError(ex);
        }
    }
    boolean z;
    byte b;
    short s;
    char c;
    int i;
    long l;
    float f;
    double d;
    String str;

    public static void main(String[] args) {
        System.out.println("total: "+calculateSize(new FieldSize())+" size");
    }
    static int calculateSize(Object o) {
        int total=0;
        for(Class cl=o.getClass(); cl!=null; cl=cl.getSuperclass()) {
            for(Field f: cl.getDeclaredFields()) {
                if(Modifier.isStatic(f.getModifiers())) continue;
                int size=getSize(f, o);
                System.out.println(f.getName()+" ("+f.getType()+"): "+size);
                total+=size;
            }
        }
        return total;
    }
}
然而,就底层操作而言,这并不是最简单的解决方案,如果您不喜欢,我完全理解这一点


在这种情况下,答案是没有简单/直接的方法来获取这些数字,因此,从类型到数字的映射或线性探索这八种可能性都是不可避免的,因此也是最简单(可用)的解决方案。

可能的重复:我以前看过,它绝对不符合我的用例。我只想在运行时获得一个对象的所有基本字段的大小。为什么?只需写入ByteArrayOutputStream并从中获取字节数组。它将是正确的大小。好吧,因为写入ByteArrayOutputStream完全没有效率,只是为了确定大小,为了实际写入到优化的格式…是的…正如我所说的,我可以使用Short.Bytes,Integer.Bytes的映射,我的问题是,这是否必要,或者是否有其他方法可以直接获得字段的大小。依赖字段的大小并不危险。这是Java,不是C。不是真的。至少在C中,您有在运行时可靠的sizeof()(当然,您应该注意指针)。在Java中,没有可靠的方法来估计对象的大小。猜猜JLS中未指定的布尔值的大小是多少?布尔数组怎么样?甚至是int数组的大小。无论如何,对象和数组的处理方式都会有所不同。我所需要的只是原语的大小,它是由它们的包装类中的常量值定义的。我只是希望有一种方法可以避免使用地图或开关来获取尺寸。唉,我想这是我能得到的最好答案。谢谢你的努力。