是否有人知道如何使用ObjectInputStream.GetField
和ObjectOutputStream.PutField
。我的程序需要在特定的时间查找特定的对象,而上述类确实可以帮助我正确地进行操作。
最佳答案
ObjectOutputStream.PutField
:
private class PutFieldImpl extends PutField {
/** class descriptor describing serializable fields */
private final ObjectStreamClass desc;
/** primitive field values */
private final byte[] primVals;
/** object field values */
private final Object[] objVals;
/**
* Creates PutFieldImpl object for writing fields defined in given
* class descriptor.
*/
PutFieldImpl(ObjectStreamClass desc) {
this.desc = desc;
primVals = new byte[desc.getPrimDataSize()];
objVals = new Object[desc.getNumObjFields()];
}
public void put(String name, boolean val) {
Bits.putBoolean(primVals, getFieldOffset(name, Boolean.TYPE), val);
}
public void put(String name, byte val) {
primVals[getFieldOffset(name, Byte.TYPE)] = val;
}
public void put(String name, char val) {
Bits.putChar(primVals, getFieldOffset(name, Character.TYPE), val);
}
public void put(String name, short val) {
Bits.putShort(primVals, getFieldOffset(name, Short.TYPE), val);
}
public void put(String name, int val) {
Bits.putInt(primVals, getFieldOffset(name, Integer.TYPE), val);
}
public void put(String name, float val) {
Bits.putFloat(primVals, getFieldOffset(name, Float.TYPE), val);
}
public void put(String name, long val) {
Bits.putLong(primVals, getFieldOffset(name, Long.TYPE), val);
}
public void put(String name, double val) {
Bits.putDouble(primVals, getFieldOffset(name, Double.TYPE), val);
}
public void put(String name, Object val) {
objVals[getFieldOffset(name, Object.class)] = val;
}
// deprecated in ObjectOutputStream.PutField
public void write(ObjectOutput out) throws IOException {
/*
* Applications should *not* use this method to write PutField
* data, as it will lead to stream corruption if the PutField
* object writes any primitive data (since block data mode is not
* unset/set properly, as is done in OOS.writeFields()). This
* broken implementation is being retained solely for behavioral
* compatibility, in order to support applications which use
* OOS.PutField.write() for writing only non-primitive data.
*
* Serialization of unshared objects is not implemented here since
* it is not necessary for backwards compatibility; also, unshared
* semantics may not be supported by the given ObjectOutput
* instance. Applications which write unshared objects using the
* PutField API must use OOS.writeFields().
*/
if (ObjectOutputStream.this != out) {
throw new IllegalArgumentException("wrong stream");
}
out.write(primVals, 0, primVals.length);
ObjectStreamField[] fields = desc.getFields(false);
int numPrimFields = fields.length - objVals.length;
// REMIND: warn if numPrimFields > 0?
for (int i = 0; i < objVals.length; i++) {
if (fields[numPrimFields + i].isUnshared()) {
throw new IOException("cannot write unshared object");
}
out.writeObject(objVals[i]);
}
}
/**
* Writes buffered primitive data and object fields to stream.
*/
void writeFields() throws IOException {
bout.write(primVals, 0, primVals.length, false);
ObjectStreamField[] fields = desc.getFields(false);
int numPrimFields = fields.length - objVals.length;
for (int i = 0; i < objVals.length; i++) {
if (extendedDebugInfo) {
debugInfoStack.push(
"field (class \"" + desc.getName() + "\", name: \"" +
fields[numPrimFields + i].getName() + "\", type: \"" +
fields[numPrimFields + i].getType() + "\")");
}
try {
writeObject0(objVals[i],
fields[numPrimFields + i].isUnshared());
} finally {
if (extendedDebugInfo) {
debugInfoStack.pop();
}
}
}
}
/**
* Returns offset of field with given name and type. A specified type
* of null matches all types, Object.class matches all non-primitive
* types, and any other non-null type matches assignable types only.
* Throws IllegalArgumentException if no matching field found.
*/
private int getFieldOffset(String name, Class type) {
ObjectStreamField field = desc.getField(name, type);
if (field == null) {
throw new IllegalArgumentException("no such field " + name +
" with type " + type);
}
return field.getOffset();
}
}
ObjectInputStream.GetField
:private class GetFieldImpl extends GetField {
/** class descriptor describing serializable fields */
private final ObjectStreamClass desc;
/** primitive field values */
private final byte[] primVals;
/** object field values */
private final Object[] objVals;
/** object field value handles */
private final int[] objHandles;
/**
* Creates GetFieldImpl object for reading fields defined in given
* class descriptor.
*/
GetFieldImpl(ObjectStreamClass desc) {
this.desc = desc;
primVals = new byte[desc.getPrimDataSize()];
objVals = new Object[desc.getNumObjFields()];
objHandles = new int[objVals.length];
}
public ObjectStreamClass getObjectStreamClass() {
return desc;
}
public boolean defaulted(String name) throws IOException {
return (getFieldOffset(name, null) < 0);
}
public boolean get(String name, boolean val) throws IOException {
int off = getFieldOffset(name, Boolean.TYPE);
return (off >= 0) ? Bits.getBoolean(primVals, off) : val;
}
public byte get(String name, byte val) throws IOException {
int off = getFieldOffset(name, Byte.TYPE);
return (off >= 0) ? primVals[off] : val;
}
public char get(String name, char val) throws IOException {
int off = getFieldOffset(name, Character.TYPE);
return (off >= 0) ? Bits.getChar(primVals, off) : val;
}
public short get(String name, short val) throws IOException {
int off = getFieldOffset(name, Short.TYPE);
return (off >= 0) ? Bits.getShort(primVals, off) : val;
}
public int get(String name, int val) throws IOException {
int off = getFieldOffset(name, Integer.TYPE);
return (off >= 0) ? Bits.getInt(primVals, off) : val;
}
public float get(String name, float val) throws IOException {
int off = getFieldOffset(name, Float.TYPE);
return (off >= 0) ? Bits.getFloat(primVals, off) : val;
}
public long get(String name, long val) throws IOException {
int off = getFieldOffset(name, Long.TYPE);
return (off >= 0) ? Bits.getLong(primVals, off) : val;
}
public double get(String name, double val) throws IOException {
int off = getFieldOffset(name, Double.TYPE);
return (off >= 0) ? Bits.getDouble(primVals, off) : val;
}
public Object get(String name, Object val) throws IOException {
int off = getFieldOffset(name, Object.class);
if (off >= 0) {
int objHandle = objHandles[off];
handles.markDependency(passHandle, objHandle);
return (handles.lookupException(objHandle) == null) ?
objVals[off] : null;
} else {
return val;
}
}
/**
* Reads primitive and object field values from stream.
*/
void readFields() throws IOException {
bin.readFully(primVals, 0, primVals.length, false);
int oldHandle = passHandle;
ObjectStreamField[] fields = desc.getFields(false);
int numPrimFields = fields.length - objVals.length;
for (int i = 0; i < objVals.length; i++) {
objVals[i] =
readObject0(fields[numPrimFields + i].isUnshared());
objHandles[i] = passHandle;
}
passHandle = oldHandle;
}
/**
* Returns offset of field with given name and type. A specified type
* of null matches all types, Object.class matches all non-primitive
* types, and any other non-null type matches assignable types only.
* If no matching field is found in the (incoming) class
* descriptor but a matching field is present in the associated local
* class descriptor, returns -1. Throws IllegalArgumentException if
* neither incoming nor local class descriptor contains a match.
*/
private int getFieldOffset(String name, Class type) {
ObjectStreamField field = desc.getField(name, type);
if (field != null) {
return field.getOffset();
} else if (desc.getLocalDesc().getField(name, type) != null) {
return -1;
} else {
throw new IllegalArgumentException("no such field " + name +
" with type " + type);
}
}
}
/ e1
通过调用
PutField
获得ObjectOutputStream#putFields
的实例,并且通过调用GetField
获得ObjectInputStream#readFields
的实例。