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