1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.classfile;
18
19 import java.io.DataInput;
20 import java.io.DataOutputStream;
21 import java.io.IOException;
22 import java.util.Objects;
23
24 import org.apache.bcel.Const;
25 import org.apache.bcel.util.BCELComparator;
26
27
28
29
30
31 public abstract class Constant implements Cloneable, Node {
32
33 static final Constant[] EMPTY_ARRAY = {};
34
35 private static BCELComparator<Constant> bcelComparator = new BCELComparator<Constant>() {
36
37 @Override
38 public boolean equals(final Constant a, final Constant b) {
39 return a == b || a != null && b != null && Objects.equals(a.toString(), b.toString());
40 }
41
42 @Override
43 public int hashCode(final Constant o) {
44 return o != null ? Objects.hashCode(o.toString()) : 0;
45 }
46 };
47
48
49
50
51 public static BCELComparator<Constant> getComparator() {
52 return bcelComparator;
53 }
54
55
56
57
58
59
60
61
62
63
64 public static Constant readConstant(final DataInput dataInput) throws IOException, ClassFormatException {
65 final byte b = dataInput.readByte();
66 switch (b) {
67 case Const.CONSTANT_Class:
68 return new ConstantClass(dataInput);
69 case Const.CONSTANT_Fieldref:
70 return new ConstantFieldref(dataInput);
71 case Const.CONSTANT_Methodref:
72 return new ConstantMethodref(dataInput);
73 case Const.CONSTANT_InterfaceMethodref:
74 return new ConstantInterfaceMethodref(dataInput);
75 case Const.CONSTANT_String:
76 return new ConstantString(dataInput);
77 case Const.CONSTANT_Integer:
78 return new ConstantInteger(dataInput);
79 case Const.CONSTANT_Float:
80 return new ConstantFloat(dataInput);
81 case Const.CONSTANT_Long:
82 return new ConstantLong(dataInput);
83 case Const.CONSTANT_Double:
84 return new ConstantDouble(dataInput);
85 case Const.CONSTANT_NameAndType:
86 return new ConstantNameAndType(dataInput);
87 case Const.CONSTANT_Utf8:
88 return ConstantUtf8.getInstance(dataInput);
89 case Const.CONSTANT_MethodHandle:
90 return new ConstantMethodHandle(dataInput);
91 case Const.CONSTANT_MethodType:
92 return new ConstantMethodType(dataInput);
93 case Const.CONSTANT_Dynamic:
94 return new ConstantDynamic(dataInput);
95 case Const.CONSTANT_InvokeDynamic:
96 return new ConstantInvokeDynamic(dataInput);
97 case Const.CONSTANT_Module:
98 return new ConstantModule(dataInput);
99 case Const.CONSTANT_Package:
100 return new ConstantPackage(dataInput);
101 default:
102 throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
103 }
104 }
105
106
107
108
109 public static void setComparator(final BCELComparator<Constant> comparator) {
110 bcelComparator = comparator;
111 }
112
113
114
115
116
117
118
119
120
121
122
123 @java.lang.Deprecated
124 protected byte tag;
125
126 Constant(final byte tag) {
127 this.tag = tag;
128 }
129
130
131
132
133
134
135
136 @Override
137 public abstract void accept(Visitor v);
138
139 @Override
140 public Object clone() {
141 try {
142 return super.clone();
143 } catch (final CloneNotSupportedException e) {
144 throw new UnsupportedOperationException("Clone Not Supported", e);
145 }
146 }
147
148
149
150
151 public Constant copy() {
152 try {
153 return (Constant) super.clone();
154 } catch (final CloneNotSupportedException e) {
155
156 }
157 return null;
158 }
159
160 public abstract void dump(DataOutputStream file) throws IOException;
161
162
163
164
165
166
167
168 @Override
169 public boolean equals(final Object obj) {
170 return obj instanceof Constant && bcelComparator.equals(this, (Constant) obj);
171 }
172
173
174
175
176 public final byte getTag() {
177 return tag;
178 }
179
180
181
182
183
184
185
186 @Override
187 public int hashCode() {
188 return bcelComparator.hashCode(this);
189 }
190
191
192
193
194 @Override
195 public String toString() {
196 return Const.getConstantName(tag) + "[" + tag + "]";
197 }
198 }