19 * limitations under the License. |
19 * limitations under the License. |
20 */ |
20 */ |
21 |
21 |
22 package com.sun.org.apache.bcel.internal.classfile; |
22 package com.sun.org.apache.bcel.internal.classfile; |
23 |
23 |
24 import com.sun.org.apache.bcel.internal.Constants; |
24 import java.io.DataInput; |
|
25 import java.io.IOException; |
|
26 |
|
27 import com.sun.org.apache.bcel.internal.Const; |
25 import com.sun.org.apache.bcel.internal.generic.Type; |
28 import com.sun.org.apache.bcel.internal.generic.Type; |
26 import java.io.*; |
29 import com.sun.org.apache.bcel.internal.util.BCELComparator; |
27 |
30 |
28 /** |
31 /** |
29 * This class represents the field info structure, i.e., the representation |
32 * This class represents the field info structure, i.e., the representation |
30 * for a variable in the class. See JVM specification for details. |
33 * for a variable in the class. See JVM specification for details. |
31 * |
34 * |
32 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> |
35 * @version $Id: Field.java 1749603 2016-06-21 20:50:19Z ggregory $ |
33 */ |
36 */ |
34 public final class Field extends FieldOrMethod { |
37 public final class Field extends FieldOrMethod { |
35 /** |
38 |
36 * Initialize from another object. Note that both objects use the same |
39 private static BCELComparator bcelComparator = new BCELComparator() { |
37 * references (shallow copy). Use clone() for a physical copy. |
40 |
38 */ |
41 @Override |
39 public Field(Field c) { |
42 public boolean equals( final Object o1, final Object o2 ) { |
40 super(c); |
43 final Field THIS = (Field) o1; |
41 } |
44 final Field THAT = (Field) o2; |
42 |
45 return THIS.getName().equals(THAT.getName()) |
43 /** |
46 && THIS.getSignature().equals(THAT.getSignature()); |
44 * Construct object from file stream. |
47 } |
45 * @param file Input stream |
48 |
46 */ |
49 |
47 Field(DataInputStream file, ConstantPool constant_pool) |
50 @Override |
48 throws IOException, ClassFormatException |
51 public int hashCode( final Object o ) { |
49 { |
52 final Field THIS = (Field) o; |
50 super(file, constant_pool); |
53 return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); |
51 } |
54 } |
52 |
55 }; |
53 /** |
56 |
54 * @param access_flags Access rights of field |
57 |
55 * @param name_index Points to field name in constant pool |
58 /** |
56 * @param signature_index Points to encoded signature |
59 * Initialize from another object. Note that both objects use the same |
57 * @param attributes Collection of attributes |
60 * references (shallow copy). Use clone() for a physical copy. |
58 * @param constant_pool Array of constants |
61 */ |
59 */ |
62 public Field(final Field c) { |
60 public Field(int access_flags, int name_index, int signature_index, |
63 super(c); |
61 Attribute[] attributes, ConstantPool constant_pool) |
64 } |
62 { |
65 |
63 super(access_flags, name_index, signature_index, attributes, constant_pool); |
66 |
64 } |
67 /** |
65 |
68 * Construct object from file stream. |
66 /** |
69 * @param file Input stream |
67 * Called by objects that are traversing the nodes of the tree implicitely |
70 */ |
68 * defined by the contents of a Java class. I.e., the hierarchy of methods, |
71 Field(final DataInput file, final ConstantPool constant_pool) throws IOException, |
69 * fields, attributes, etc. spawns a tree of objects. |
72 ClassFormatException { |
70 * |
73 super(file, constant_pool); |
71 * @param v Visitor object |
74 } |
72 */ |
75 |
73 public void accept(Visitor v) { |
76 |
74 v.visitField(this); |
77 /** |
75 } |
78 * @param access_flags Access rights of field |
76 |
79 * @param name_index Points to field name in constant pool |
77 /** |
80 * @param signature_index Points to encoded signature |
78 * @return constant value associated with this field (may be null) |
81 * @param attributes Collection of attributes |
79 */ |
82 * @param constant_pool Array of constants |
80 public final ConstantValue getConstantValue() { |
83 */ |
81 for(int i=0; i < attributes_count; i++) |
84 public Field(final int access_flags, final int name_index, final int signature_index, final Attribute[] attributes, |
82 if(attributes[i].getTag() == Constants.ATTR_CONSTANT_VALUE) |
85 final ConstantPool constant_pool) { |
83 return (ConstantValue)attributes[i]; |
86 super(access_flags, name_index, signature_index, attributes, constant_pool); |
84 |
87 } |
85 return null; |
88 |
86 } |
89 |
87 |
90 /** |
88 /** |
91 * Called by objects that are traversing the nodes of the tree implicitely |
89 * Return string representation close to declaration format, |
92 * defined by the contents of a Java class. I.e., the hierarchy of methods, |
90 * `public static final short MAX = 100', e.g.. |
93 * fields, attributes, etc. spawns a tree of objects. |
91 * |
94 * |
92 * @return String representation of field, including the signature. |
95 * @param v Visitor object |
93 */ |
96 */ |
94 public final String toString() { |
97 @Override |
95 String name, signature, access; // Short cuts to constant pool |
98 public void accept( final Visitor v ) { |
96 |
99 v.visitField(this); |
97 // Get names from constant pool |
100 } |
98 access = Utility.accessToString(access_flags); |
101 |
99 access = access.equals("")? "" : (access + " "); |
102 |
100 signature = Utility.signatureToString(getSignature()); |
103 /** |
101 name = getName(); |
104 * @return constant value associated with this field (may be null) |
102 |
105 */ |
103 StringBuffer buf = new StringBuffer(access + signature + " " + name); |
106 public final ConstantValue getConstantValue() { |
104 ConstantValue cv = getConstantValue(); |
107 for (final Attribute attribute : super.getAttributes()) { |
105 |
108 if (attribute.getTag() == Const.ATTR_CONSTANT_VALUE) { |
106 if(cv != null) |
109 return (ConstantValue) attribute; |
107 buf.append(" = " + cv); |
110 } |
108 |
111 } |
109 for(int i=0; i < attributes_count; i++) { |
112 return null; |
110 Attribute a = attributes[i]; |
113 } |
111 |
114 |
112 if(!(a instanceof ConstantValue)) |
115 |
113 buf.append(" [" + a.toString() + "]"); |
116 /** |
114 } |
117 * Return string representation close to declaration format, |
115 |
118 * `public static final short MAX = 100', e.g.. |
116 return buf.toString(); |
119 * |
117 } |
120 * @return String representation of field, including the signature. |
118 |
121 */ |
119 /** |
122 @Override |
120 * @return deep copy of this field |
123 public final String toString() { |
121 */ |
124 String name; |
122 public final Field copy(ConstantPool constant_pool) { |
125 String signature; |
123 return (Field)copy_(constant_pool); |
126 String access; // Short cuts to constant pool |
124 } |
127 |
125 |
128 // Get names from constant pool |
126 /** |
129 access = Utility.accessToString(super.getAccessFlags()); |
127 * @return type of field |
130 access = access.isEmpty() ? "" : (access + " "); |
128 */ |
131 signature = Utility.signatureToString(getSignature()); |
129 public Type getType() { |
132 name = getName(); |
130 return Type.getReturnType(getSignature()); |
133 final StringBuilder buf = new StringBuilder(64); // CHECKSTYLE IGNORE MagicNumber |
131 } |
134 buf.append(access).append(signature).append(" ").append(name); |
|
135 final ConstantValue cv = getConstantValue(); |
|
136 if (cv != null) { |
|
137 buf.append(" = ").append(cv); |
|
138 } |
|
139 for (final Attribute attribute : super.getAttributes()) { |
|
140 if (!(attribute instanceof ConstantValue)) { |
|
141 buf.append(" [").append(attribute).append("]"); |
|
142 } |
|
143 } |
|
144 return buf.toString(); |
|
145 } |
|
146 |
|
147 |
|
148 /** |
|
149 * @return deep copy of this field |
|
150 */ |
|
151 public final Field copy( final ConstantPool _constant_pool ) { |
|
152 return (Field) copy_(_constant_pool); |
|
153 } |
|
154 |
|
155 |
|
156 /** |
|
157 * @return type of field |
|
158 */ |
|
159 public Type getType() { |
|
160 return Type.getReturnType(getSignature()); |
|
161 } |
|
162 |
|
163 |
|
164 /** |
|
165 * @return Comparison strategy object |
|
166 */ |
|
167 public static BCELComparator getComparator() { |
|
168 return bcelComparator; |
|
169 } |
|
170 |
|
171 |
|
172 /** |
|
173 * @param comparator Comparison strategy object |
|
174 */ |
|
175 public static void setComparator( final BCELComparator comparator ) { |
|
176 bcelComparator = comparator; |
|
177 } |
|
178 |
|
179 |
|
180 /** |
|
181 * Return value as defined by given BCELComparator strategy. |
|
182 * By default two Field objects are said to be equal when |
|
183 * their names and signatures are equal. |
|
184 * |
|
185 * @see java.lang.Object#equals(java.lang.Object) |
|
186 */ |
|
187 @Override |
|
188 public boolean equals( final Object obj ) { |
|
189 return bcelComparator.equals(this, obj); |
|
190 } |
|
191 |
|
192 |
|
193 /** |
|
194 * Return value as defined by given BCELComparator strategy. |
|
195 * By default return the hashcode of the field's name XOR signature. |
|
196 * |
|
197 * @see java.lang.Object#hashCode() |
|
198 */ |
|
199 @Override |
|
200 public int hashCode() { |
|
201 return bcelComparator.hashCode(this); |
|
202 } |
132 } |
203 } |