1. /*
  2. * @(#)ObjectStreamField.java 1.45 04/05/05
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.io;
  8. import java.lang.reflect.Field;
  9. /**
  10. * A description of a Serializable field from a Serializable class. An array
  11. * of ObjectStreamFields is used to declare the Serializable fields of a class.
  12. *
  13. * @author Mike Warres
  14. * @author Roger Riggs
  15. * @version 1.45, 04/05/05
  16. * @see ObjectStreamClass
  17. * @since 1.2
  18. */
  19. public class ObjectStreamField
  20. implements Comparable<Object>
  21. {
  22. /** field name */
  23. private final String name;
  24. /** canonical JVM signature of field type */
  25. private final String signature;
  26. /** field type (Object.class if unknown non-primitive type) */
  27. private final Class type;
  28. /** whether or not to (de)serialize field values as unshared */
  29. private final boolean unshared;
  30. /** corresponding reflective field object, if any */
  31. private final Field field;
  32. /** offset of field value in enclosing field group */
  33. private int offset = 0;
  34. /**
  35. * Create a Serializable field with the specified type. This field should
  36. * be documented with a <code>serialField</code> tag.
  37. *
  38. * @param name the name of the serializable field
  39. * @param type the <code>Class</code> object of the serializable field
  40. */
  41. public ObjectStreamField(String name, Class<?> type) {
  42. this(name, type, false);
  43. }
  44. /**
  45. * Creates an ObjectStreamField representing a serializable field with the
  46. * given name and type. If unshared is false, values of the represented
  47. * field are serialized and deserialized in the default manner--if the
  48. * field is non-primitive, object values are serialized and deserialized as
  49. * if they had been written and read by calls to writeObject and
  50. * readObject. If unshared is true, values of the represented field are
  51. * serialized and deserialized as if they had been written and read by
  52. * calls to writeUnshared and readUnshared.
  53. *
  54. * @param name field name
  55. * @param type field type
  56. * @param unshared if false, write/read field values in the same manner
  57. * as writeObject/readObject; if true, write/read in the same
  58. * manner as writeUnshared/readUnshared
  59. */
  60. public ObjectStreamField(String name, Class<?> type, boolean unshared) {
  61. if (name == null) {
  62. throw new NullPointerException();
  63. }
  64. this.name = name;
  65. this.type = type;
  66. this.unshared = unshared;
  67. signature = ObjectStreamClass.getClassSignature(type).intern();
  68. field = null;
  69. }
  70. /**
  71. * Creates an ObjectStreamField representing a field with the given name,
  72. * signature and unshared setting.
  73. */
  74. ObjectStreamField(String name, String signature, boolean unshared) {
  75. if (name == null) {
  76. throw new NullPointerException();
  77. }
  78. this.name = name;
  79. this.signature = signature.intern();
  80. this.unshared = unshared;
  81. field = null;
  82. switch (signature.charAt(0)) {
  83. case 'Z': type = Boolean.TYPE; break;
  84. case 'B': type = Byte.TYPE; break;
  85. case 'C': type = Character.TYPE; break;
  86. case 'S': type = Short.TYPE; break;
  87. case 'I': type = Integer.TYPE; break;
  88. case 'J': type = Long.TYPE; break;
  89. case 'F': type = Float.TYPE; break;
  90. case 'D': type = Double.TYPE; break;
  91. case 'L':
  92. case '[': type = Object.class; break;
  93. default: throw new IllegalArgumentException("illegal signature");
  94. }
  95. }
  96. /**
  97. * Creates an ObjectStreamField representing the given field with the
  98. * specified unshared setting. For compatibility with the behavior of
  99. * earlier serialization implementations, a "showType" parameter is
  100. * necessary to govern whether or not a getType() call on this
  101. * ObjectStreamField (if non-primitive) will return Object.class (as
  102. * opposed to a more specific reference type).
  103. */
  104. ObjectStreamField(Field field, boolean unshared, boolean showType) {
  105. this.field = field;
  106. this.unshared = unshared;
  107. name = field.getName();
  108. Class ftype = field.getType();
  109. type = (showType || ftype.isPrimitive()) ? ftype : Object.class;
  110. signature = ObjectStreamClass.getClassSignature(ftype).intern();
  111. }
  112. /**
  113. * Get the name of this field.
  114. *
  115. * @return a <code>String</code> representing the name of the serializable
  116. * field
  117. */
  118. public String getName() {
  119. return name;
  120. }
  121. /**
  122. * Get the type of the field. If the type is non-primitive and this
  123. * <code>ObjectStreamField</code> was obtained from a deserialized {@link
  124. * ObjectStreamClass} instance, then <code>Object.class</code> is returned.
  125. * Otherwise, the <code>Class</code> object for the type of the field is
  126. * returned.
  127. *
  128. * @return a <code>Class</code> object representing the type of the
  129. * serializable field
  130. */
  131. public Class<?> getType() {
  132. return type;
  133. }
  134. /**
  135. * Returns character encoding of field type. The encoding is as follows:
  136. * <blockquote><pre>
  137. * B byte
  138. * C char
  139. * D double
  140. * F float
  141. * I int
  142. * J long
  143. * L class or interface
  144. * S short
  145. * Z boolean
  146. * [ array
  147. * </pre></blockquote>
  148. *
  149. * @return the typecode of the serializable field
  150. */
  151. // REMIND: deprecate?
  152. public char getTypeCode() {
  153. return signature.charAt(0);
  154. }
  155. /**
  156. * Return the JVM type signature.
  157. *
  158. * @return null if this field has a primitive type.
  159. */
  160. // REMIND: deprecate?
  161. public String getTypeString() {
  162. return isPrimitive() ? null : signature;
  163. }
  164. /**
  165. * Offset of field within instance data.
  166. *
  167. * @return the offset of this field
  168. * @see #setOffset
  169. */
  170. // REMIND: deprecate?
  171. public int getOffset() {
  172. return offset;
  173. }
  174. /**
  175. * Offset within instance data.
  176. *
  177. * @param offset the offset of the field
  178. * @see #getOffset
  179. */
  180. // REMIND: deprecate?
  181. protected void setOffset(int offset) {
  182. this.offset = offset;
  183. }
  184. /**
  185. * Return true if this field has a primitive type.
  186. *
  187. * @return true if and only if this field corresponds to a primitive type
  188. */
  189. // REMIND: deprecate?
  190. public boolean isPrimitive() {
  191. char tcode = signature.charAt(0);
  192. return ((tcode != 'L') && (tcode != '['));
  193. }
  194. /**
  195. * Returns boolean value indicating whether or not the serializable field
  196. * represented by this ObjectStreamField instance is unshared.
  197. */
  198. public boolean isUnshared() {
  199. return unshared;
  200. }
  201. /**
  202. * Compare this field with another <code>ObjectStreamField</code>. Return
  203. * -1 if this is smaller, 0 if equal, 1 if greater. Types that are
  204. * primitives are "smaller" than object types. If equal, the field names
  205. * are compared.
  206. */
  207. // REMIND: deprecate?
  208. public int compareTo(Object obj) {
  209. ObjectStreamField other = (ObjectStreamField) obj;
  210. boolean isPrim = isPrimitive();
  211. if (isPrim != other.isPrimitive()) {
  212. return isPrim ? -1 : 1;
  213. }
  214. return name.compareTo(other.name);
  215. }
  216. /**
  217. * Return a string that describes this field.
  218. */
  219. public String toString() {
  220. return signature + ' ' + name;
  221. }
  222. /**
  223. * Returns field represented by this ObjectStreamField, or null if
  224. * ObjectStreamField is not associated with an actual field.
  225. */
  226. Field getField() {
  227. return field;
  228. }
  229. /**
  230. * Returns JVM type signature of field (similar to getTypeString, except
  231. * that signature strings are returned for primitive fields as well).
  232. */
  233. String getSignature() {
  234. return signature;
  235. }
  236. }