1 /*
2 * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
40 * @since 1.2
41 */
42 public class ObjectStreamField
43 implements Comparable<Object>
44 {
45
46 /** field name */
47 private final String name;
48 /** canonical JVM signature of field type, if given */
49 private final String signature;
50 /** field type (Object.class if unknown non-primitive type) */
51 private final Class<?> type;
52 /** lazily constructed signature for the type, if no explicit signature */
53 private String typeSignature;
54 /** whether or not to (de)serialize field values as unshared */
55 private final boolean unshared;
56 /** corresponding reflective field object, if any */
57 private final Field field;
58 /** offset of field value in enclosing field group */
59 private int offset;
60
61 /**
62 * Create a Serializable field with the specified type. This field should
63 * be documented with a {@code serialField} tag.
64 *
65 * @param name the name of the serializable field
66 * @param type the {@code Class} object of the serializable field
67 */
68 public ObjectStreamField(String name, Class<?> type) {
69 this(name, type, false);
70 }
71
72 /**
73 * Creates an ObjectStreamField representing a serializable field with the
74 * given name and type. If unshared is false, values of the represented
75 * field are serialized and deserialized in the default manner--if the
76 * field is non-primitive, object values are serialized and deserialized as
77 * if they had been written and read by calls to writeObject and
78 * readObject. If unshared is true, values of the represented field are
79 * serialized and deserialized as if they had been written and read by
80 * calls to writeUnshared and readUnshared.
81 *
82 * @param name field name
83 * @param type field type
84 * @param unshared if false, write/read field values in the same manner
85 * as writeObject/readObject; if true, write/read in the same
86 * manner as writeUnshared/readUnshared
87 * @since 1.4
88 */
89 public ObjectStreamField(String name, Class<?> type, boolean unshared) {
90 if (name == null) {
91 throw new NullPointerException();
92 }
93 this.name = name;
94 this.type = type;
95 this.unshared = unshared;
96 this.field = null;
97 this.signature = null;
98 }
99
100 /**
101 * Creates an ObjectStreamField representing a field with the given name,
102 * signature and unshared setting.
103 */
104 ObjectStreamField(String name, String signature, boolean unshared) {
105 if (name == null) {
106 throw new NullPointerException();
107 }
108 this.name = name;
109 this.signature = signature.intern();
110 this.unshared = unshared;
111 this.field = null;
112
113 type = switch (signature.charAt(0)) {
114 case 'Z' -> Boolean.TYPE;
115 case 'B' -> Byte.TYPE;
116 case 'C' -> Character.TYPE;
117 case 'S' -> Short.TYPE;
118 case 'I' -> Integer.TYPE;
119 case 'J' -> Long.TYPE;
120 case 'F' -> Float.TYPE;
121 case 'D' -> Double.TYPE;
122 case 'L', '[' -> Object.class;
123 default -> throw new IllegalArgumentException("illegal signature");
124 };
125 }
126
127 /**
128 * Creates an ObjectStreamField representing the given field with the
129 * specified unshared setting. For compatibility with the behavior of
130 * earlier serialization implementations, a "showType" parameter is
131 * necessary to govern whether or not a getType() call on this
132 * ObjectStreamField (if non-primitive) will return Object.class (as
133 * opposed to a more specific reference type).
134 */
135 ObjectStreamField(Field field, boolean unshared, boolean showType) {
136 this.field = field;
137 this.unshared = unshared;
138 name = field.getName();
139 Class<?> ftype = field.getType();
140 type = (showType || ftype.isPrimitive()) ? ftype : Object.class;
141 signature = ftype.descriptorString().intern();
142 }
143
144 /**
145 * Get the name of this field.
146 *
147 * @return a {@code String} representing the name of the serializable
148 * field
149 */
150 public String getName() {
151 return name;
152 }
153
154 /**
155 * Get the type of the field. If the type is non-primitive and this
156 * {@code ObjectStreamField} was obtained from a deserialized {@link
157 * ObjectStreamClass} instance, then {@code Object.class} is returned.
158 * Otherwise, the {@code Class} object for the type of the field is
159 * returned.
160 *
161 * @return a {@code Class} object representing the type of the
210 *
211 * @return the offset of this field
212 * @see #setOffset
213 */
214 // REMIND: deprecate?
215 public int getOffset() {
216 return offset;
217 }
218
219 /**
220 * Offset within instance data.
221 *
222 * @param offset the offset of the field
223 * @see #getOffset
224 */
225 // REMIND: deprecate?
226 protected void setOffset(int offset) {
227 this.offset = offset;
228 }
229
230 /**
231 * Return true if this field has a primitive type.
232 *
233 * @return true if and only if this field corresponds to a primitive type
234 */
235 // REMIND: deprecate?
236 public boolean isPrimitive() {
237 char tcode = getTypeCode();
238 return ((tcode != 'L') && (tcode != '['));
239 }
240
241 /**
242 * Returns boolean value indicating whether or not the serializable field
243 * represented by this ObjectStreamField instance is unshared.
244 *
245 * @return {@code true} if this field is unshared
246 *
247 * @since 1.4
248 */
249 public boolean isUnshared() {
|
1 /*
2 * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
40 * @since 1.2
41 */
42 public class ObjectStreamField
43 implements Comparable<Object>
44 {
45
46 /** field name */
47 private final String name;
48 /** canonical JVM signature of field type, if given */
49 private final String signature;
50 /** field type (Object.class if unknown non-primitive type) */
51 private final Class<?> type;
52 /** lazily constructed signature for the type, if no explicit signature */
53 private String typeSignature;
54 /** whether or not to (de)serialize field values as unshared */
55 private final boolean unshared;
56 /** corresponding reflective field object, if any */
57 private final Field field;
58 /** offset of field value in enclosing field group */
59 private int offset;
60 /** index of the field in the class, retain the declaration order of serializable fields */
61 private final int argIndex;
62
63 /**
64 * Create a Serializable field with the specified type. This field should
65 * be documented with a {@code serialField} tag.
66 *
67 * @param name the name of the serializable field
68 * @param type the {@code Class} object of the serializable field
69 */
70 public ObjectStreamField(String name, Class<?> type) {
71 this(name, type, false);
72 }
73
74 /**
75 * Creates an ObjectStreamField representing a serializable field with the
76 * given name and type. If unshared is false, values of the represented
77 * field are serialized and deserialized in the default manner--if the
78 * field is non-primitive, object values are serialized and deserialized as
79 * if they had been written and read by calls to writeObject and
80 * readObject. If unshared is true, values of the represented field are
81 * serialized and deserialized as if they had been written and read by
82 * calls to writeUnshared and readUnshared.
83 *
84 * @param name field name
85 * @param type field type
86 * @param unshared if false, write/read field values in the same manner
87 * as writeObject/readObject; if true, write/read in the same
88 * manner as writeUnshared/readUnshared
89 * @since 1.4
90 */
91 public ObjectStreamField(String name, Class<?> type, boolean unshared) {
92 this(name, type, unshared, -1);
93 }
94
95 /* package-private */
96 ObjectStreamField(String name, Class<?> type, boolean unshared, int argIndex) {
97 if (name == null) {
98 throw new NullPointerException();
99 }
100 this.name = name;
101 this.type = type;
102 this.unshared = unshared;
103 this.field = null;
104 this.signature = null;
105 this.argIndex = argIndex;
106 }
107
108 /**
109 * Creates an ObjectStreamField representing a field with the given name,
110 * signature and unshared setting.
111 */
112 ObjectStreamField(String name, String signature, boolean unshared, int argIndex) {
113 if (name == null) {
114 throw new NullPointerException();
115 }
116 this.name = name;
117 this.signature = signature.intern();
118 this.unshared = unshared;
119 this.field = null;
120 this.argIndex = argIndex;
121
122 type = switch (signature.charAt(0)) {
123 case 'Z' -> Boolean.TYPE;
124 case 'B' -> Byte.TYPE;
125 case 'C' -> Character.TYPE;
126 case 'S' -> Short.TYPE;
127 case 'I' -> Integer.TYPE;
128 case 'J' -> Long.TYPE;
129 case 'F' -> Float.TYPE;
130 case 'D' -> Double.TYPE;
131 case 'L', '[' -> Object.class;
132 default -> throw new IllegalArgumentException("illegal signature");
133 };
134 }
135
136 /**
137 * Creates an ObjectStreamField representing the given field with the
138 * specified unshared setting. For compatibility with the behavior of
139 * earlier serialization implementations, a "showType" parameter is
140 * necessary to govern whether or not a getType() call on this
141 * ObjectStreamField (if non-primitive) will return Object.class (as
142 * opposed to a more specific reference type).
143 */
144 ObjectStreamField(Field field, boolean unshared, boolean showType, int argIndex) {
145 this.field = field;
146 this.unshared = unshared;
147 name = field.getName();
148 Class<?> ftype = field.getType();
149 type = (showType || ftype.isPrimitive()) ? ftype : Object.class;
150 signature = ftype.descriptorString().intern();
151 this.argIndex = argIndex;
152 }
153
154 /**
155 * Get the name of this field.
156 *
157 * @return a {@code String} representing the name of the serializable
158 * field
159 */
160 public String getName() {
161 return name;
162 }
163
164 /**
165 * Get the type of the field. If the type is non-primitive and this
166 * {@code ObjectStreamField} was obtained from a deserialized {@link
167 * ObjectStreamClass} instance, then {@code Object.class} is returned.
168 * Otherwise, the {@code Class} object for the type of the field is
169 * returned.
170 *
171 * @return a {@code Class} object representing the type of the
220 *
221 * @return the offset of this field
222 * @see #setOffset
223 */
224 // REMIND: deprecate?
225 public int getOffset() {
226 return offset;
227 }
228
229 /**
230 * Offset within instance data.
231 *
232 * @param offset the offset of the field
233 * @see #getOffset
234 */
235 // REMIND: deprecate?
236 protected void setOffset(int offset) {
237 this.offset = offset;
238 }
239
240 /**
241 * {@return Index of the field in the sequence of Serializable fields}
242 */
243 int getArgIndex() {
244 return argIndex;
245 }
246
247 /**
248 * Return true if this field has a primitive type.
249 *
250 * @return true if and only if this field corresponds to a primitive type
251 */
252 // REMIND: deprecate?
253 public boolean isPrimitive() {
254 char tcode = getTypeCode();
255 return ((tcode != 'L') && (tcode != '['));
256 }
257
258 /**
259 * Returns boolean value indicating whether or not the serializable field
260 * represented by this ObjectStreamField instance is unshared.
261 *
262 * @return {@code true} if this field is unshared
263 *
264 * @since 1.4
265 */
266 public boolean isUnshared() {
|