我正在写一个小的序列化实用程序,我想计算将一个对象写入字节数组需要保留多少字节。假设我有一堂课,其中有一些字段/获取者,例如
int age;
String name;
Colour colour;
boolean active;
...
我以为可以使用反射遍历字段并查看它们的大小,但是我所能做的就是检查它们是否原始。这是一个开始,因为我将short用作Objects的偏移量。好吧,我可以用
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);
}
因此,我想知道字节数组的所需大小,以便避免以后进行检查和调整大小的工作。
好了,您已经知道该BYTES
字段,问题是,这些字段是在相应的包装器类型中声明的,没有简单的方法来获取原始类型的包装器类型。就代码大小而言,最简单的获取方法是通过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;
}
}
但是,就底层操作而言,它不是最简单的解决方案,如果您不喜欢它,我将完全理解。
在那种情况下,答案是没有简单/直接的方法来获取这些数字,因此不可避免地要进行从类型到数字的映射或对这八种可能性进行线性探测,因此也是最简单的(可用的)解决方案。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句