28 import java.lang.reflect.Field;
29 import jdk.internal.reflect.CallerSensitive;
30 import jdk.internal.reflect.Reflection;
31 import sun.reflect.misc.ReflectUtil;
32
33 /**
34 * A description of a Serializable field from a Serializable class. An array
35 * of ObjectStreamFields is used to declare the Serializable fields of a class.
36 *
37 * @author Mike Warres
38 * @author Roger Riggs
39 * @see ObjectStreamClass
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 */
49 private final String signature;
50 /** field type (Object.class if unknown non-primitive type) */
51 private final Class<?> type;
52 /** whether or not to (de)serialize field values as unshared */
53 private final boolean unshared;
54 /** corresponding reflective field object, if any */
55 private final Field field;
56 /** offset of field value in enclosing field group */
57 private int offset = 0;
58
59 /**
60 * Create a Serializable field with the specified type. This field should
61 * be documented with a <code>serialField</code> tag.
62 *
63 * @param name the name of the serializable field
64 * @param type the <code>Class</code> object of the serializable field
65 */
66 public ObjectStreamField(String name, Class<?> type) {
67 this(name, type, false);
68 }
69
70 /**
71 * Creates an ObjectStreamField representing a serializable field with the
72 * given name and type. If unshared is false, values of the represented
73 * field are serialized and deserialized in the default manner--if the
74 * field is non-primitive, object values are serialized and deserialized as
75 * if they had been written and read by calls to writeObject and
76 * readObject. If unshared is true, values of the represented field are
77 * serialized and deserialized as if they had been written and read by
78 * calls to writeUnshared and readUnshared.
79 *
80 * @param name field name
81 * @param type field type
82 * @param unshared if false, write/read field values in the same manner
83 * as writeObject/readObject; if true, write/read in the same
84 * manner as writeUnshared/readUnshared
85 * @since 1.4
86 */
87 public ObjectStreamField(String name, Class<?> type, boolean unshared) {
88 if (name == null) {
89 throw new NullPointerException();
90 }
91 this.name = name;
92 this.type = type;
93 this.unshared = unshared;
94 signature = getClassSignature(type).intern();
95 field = null;
96 }
97
98 /**
99 * Creates an ObjectStreamField representing a field with the given name,
100 * signature and unshared setting.
101 */
102 ObjectStreamField(String name, String signature, boolean unshared) {
103 if (name == null) {
104 throw new NullPointerException();
105 }
106 this.name = name;
107 this.signature = signature.intern();
108 this.unshared = unshared;
109 field = null;
110
111 switch (signature.charAt(0)) {
112 case 'Z': type = Boolean.TYPE; break;
113 case 'B': type = Byte.TYPE; break;
114 case 'C': type = Character.TYPE; break;
115 case 'S': type = Short.TYPE; break;
116 case 'I': type = Integer.TYPE; break;
117 case 'J': type = Long.TYPE; break;
118 case 'F': type = Float.TYPE; break;
119 case 'D': type = Double.TYPE; break;
120 case 'L':
121 case '[': type = Object.class; break;
122 default: throw new IllegalArgumentException("illegal signature");
123 }
124 }
125
126 /**
127 * Returns JVM type signature for given primitive.
128 */
129 private static String getPrimitiveSignature(Class<?> cl) {
225
226 /**
227 * Returns character encoding of field type. The encoding is as follows:
228 * <blockquote><pre>
229 * B byte
230 * C char
231 * D double
232 * F float
233 * I int
234 * J long
235 * L class or interface
236 * S short
237 * Z boolean
238 * [ array
239 * </pre></blockquote>
240 *
241 * @return the typecode of the serializable field
242 */
243 // REMIND: deprecate?
244 public char getTypeCode() {
245 return signature.charAt(0);
246 }
247
248 /**
249 * Return the JVM type signature.
250 *
251 * @return null if this field has a primitive type.
252 */
253 // REMIND: deprecate?
254 public String getTypeString() {
255 return isPrimitive() ? null : signature;
256 }
257
258 /**
259 * Offset of field within instance data.
260 *
261 * @return the offset of this field
262 * @see #setOffset
263 */
264 // REMIND: deprecate?
265 public int getOffset() {
266 return offset;
267 }
268
269 /**
270 * Offset within instance data.
271 *
272 * @param offset the offset of the field
273 * @see #getOffset
274 */
275 // REMIND: deprecate?
276 protected void setOffset(int offset) {
277 this.offset = offset;
278 }
279
280 /**
281 * Return true if this field has a primitive type.
282 *
283 * @return true if and only if this field corresponds to a primitive type
284 */
285 // REMIND: deprecate?
286 public boolean isPrimitive() {
287 char tcode = signature.charAt(0);
288 return ((tcode != 'L') && (tcode != '['));
289 }
290
291 /**
292 * Returns boolean value indicating whether or not the serializable field
293 * represented by this ObjectStreamField instance is unshared.
294 *
295 * @return {@code true} if this field is unshared
296 *
297 * @since 1.4
298 */
299 public boolean isUnshared() {
300 return unshared;
301 }
302
303 /**
304 * Compare this field with another <code>ObjectStreamField</code>. Return
305 * -1 if this is smaller, 0 if equal, 1 if greater. Types that are
306 * primitives are "smaller" than object types. If equal, the field names
307 * are compared.
308 */
309 // REMIND: deprecate?
310 public int compareTo(Object obj) {
311 ObjectStreamField other = (ObjectStreamField) obj;
312 boolean isPrim = isPrimitive();
313 if (isPrim != other.isPrimitive()) {
314 return isPrim ? -1 : 1;
315 }
316 return name.compareTo(other.name);
317 }
318
319 /**
320 * Return a string that describes this field.
321 */
322 public String toString() {
323 return signature + ' ' + name;
324 }
325
326 /**
327 * Returns field represented by this ObjectStreamField, or null if
328 * ObjectStreamField is not associated with an actual field.
329 */
330 Field getField() {
331 return field;
332 }
333
334 /**
335 * Returns JVM type signature of field (similar to getTypeString, except
336 * that signature strings are returned for primitive fields as well).
337 */
338 String getSignature() {
339 return signature;
340 }
341 }
|
28 import java.lang.reflect.Field;
29 import jdk.internal.reflect.CallerSensitive;
30 import jdk.internal.reflect.Reflection;
31 import sun.reflect.misc.ReflectUtil;
32
33 /**
34 * A description of a Serializable field from a Serializable class. An array
35 * of ObjectStreamFields is used to declare the Serializable fields of a class.
36 *
37 * @author Mike Warres
38 * @author Roger Riggs
39 * @see ObjectStreamClass
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</code> tag.
64 *
65 * @param name the name of the serializable field
66 * @param type the <code>Class</code> 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 switch (signature.charAt(0)) {
114 case 'Z': type = Boolean.TYPE; break;
115 case 'B': type = Byte.TYPE; break;
116 case 'C': type = Character.TYPE; break;
117 case 'S': type = Short.TYPE; break;
118 case 'I': type = Integer.TYPE; break;
119 case 'J': type = Long.TYPE; break;
120 case 'F': type = Float.TYPE; break;
121 case 'D': type = Double.TYPE; break;
122 case 'L':
123 case '[': type = Object.class; break;
124 default: throw new IllegalArgumentException("illegal signature");
125 }
126 }
127
128 /**
129 * Returns JVM type signature for given primitive.
130 */
131 private static String getPrimitiveSignature(Class<?> cl) {
227
228 /**
229 * Returns character encoding of field type. The encoding is as follows:
230 * <blockquote><pre>
231 * B byte
232 * C char
233 * D double
234 * F float
235 * I int
236 * J long
237 * L class or interface
238 * S short
239 * Z boolean
240 * [ array
241 * </pre></blockquote>
242 *
243 * @return the typecode of the serializable field
244 */
245 // REMIND: deprecate?
246 public char getTypeCode() {
247 return getSignature().charAt(0);
248 }
249
250 /**
251 * Return the JVM type signature.
252 *
253 * @return null if this field has a primitive type.
254 */
255 // REMIND: deprecate?
256 public String getTypeString() {
257 return isPrimitive() ? null : getSignature();
258 }
259
260 /**
261 * Offset of field within instance data.
262 *
263 * @return the offset of this field
264 * @see #setOffset
265 */
266 // REMIND: deprecate?
267 public int getOffset() {
268 return offset;
269 }
270
271 /**
272 * Offset within instance data.
273 *
274 * @param offset the offset of the field
275 * @see #getOffset
276 */
277 // REMIND: deprecate?
278 protected void setOffset(int offset) {
279 this.offset = offset;
280 }
281
282 /**
283 * Return true if this field has a primitive type.
284 *
285 * @return true if and only if this field corresponds to a primitive type
286 */
287 // REMIND: deprecate?
288 public boolean isPrimitive() {
289 char tcode = getTypeCode();
290 return ((tcode != 'L') && (tcode != '['));
291 }
292
293 /**
294 * Returns boolean value indicating whether or not the serializable field
295 * represented by this ObjectStreamField instance is unshared.
296 *
297 * @return {@code true} if this field is unshared
298 *
299 * @since 1.4
300 */
301 public boolean isUnshared() {
302 return unshared;
303 }
304
305 /**
306 * Compare this field with another <code>ObjectStreamField</code>. Return
307 * -1 if this is smaller, 0 if equal, 1 if greater. Types that are
308 * primitives are "smaller" than object types. If equal, the field names
309 * are compared.
310 */
311 // REMIND: deprecate?
312 public int compareTo(Object obj) {
313 ObjectStreamField other = (ObjectStreamField) obj;
314 boolean isPrim = isPrimitive();
315 if (isPrim != other.isPrimitive()) {
316 return isPrim ? -1 : 1;
317 }
318 return name.compareTo(other.name);
319 }
320
321 /**
322 * Return a string that describes this field.
323 */
324 public String toString() {
325 return getSignature() + ' ' + name;
326 }
327
328 /**
329 * Returns field represented by this ObjectStreamField, or null if
330 * ObjectStreamField is not associated with an actual field.
331 */
332 Field getField() {
333 return field;
334 }
335
336 /**
337 * Returns JVM type signature of field (similar to getTypeString, except
338 * that signature strings are returned for primitive fields as well).
339 */
340 String getSignature() {
341 if (signature != null) {
342 return signature;
343 }
344
345 String sig = typeSignature;
346 // This lazy calculation is safe since signature can be null iff one
347 // of the public constructors are used, in which case type is always
348 // initialized to the exact type we want the signature to represent.
349 if (sig == null) {
350 typeSignature = sig = getClassSignature(type).intern();
351 }
352 return sig;
353 }
354 }
|