是否有人知道如何使用ObjectInputStream.GetFieldObjectOutputStream.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的实例。

09-25 22:24