📄 classwriter.java
字号:
} else if (cst instanceof Float) {
float val = ((Float)cst).floatValue();
return newFloat(val);
} else if (cst instanceof Long) {
long val = ((Long)cst).longValue();
return newLong(val);
} else if (cst instanceof Double) {
double val = ((Double)cst).doubleValue();
return newDouble(val);
} else if (cst instanceof String) {
return newString((String)cst);
} else if (cst instanceof Type) {
Type t = (Type)cst;
return newClassItem(
t.getSort() == Type.OBJECT ? t.getInternalName() : t.getDescriptor());
} else {
throw new IllegalArgumentException("value " + cst);
}
}
/**
* Adds a number or string constant to the constant pool of the class being
* build. Does nothing if the constant pool already contains a similar item.
* <i>This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.</i>
*
* @param cst the value of the constant to be added to the constant pool. This
* parameter must be an {@link java.lang.Integer Integer}, a {@link
* java.lang.Float Float}, a {@link java.lang.Long Long}, a {@link
java.lang.Double Double} or a {@link String String}.
* @return the index of a new or already existing constant item with the given
* value.
*/
public int newConst (final Object cst) {
return newConstItem(cst).index;
}
public int newConstInt (final int i) {
return newInteger(i).index;
}
public int newConstLong (final long l) {
return newLong(l).index;
}
public int newConstFloat (final float f) {
return newFloat(f).index;
}
public int newConstDouble (final double d) {
return newDouble(d).index;
}
/**
* Adds an UTF8 string to the constant pool of the class being build. Does
* nothing if the constant pool already contains a similar item. <i>This
* method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.</i>
*
* @param value the String value.
* @return the index of a new or already existing UTF8 item.
*/
public int newUTF8 (final String value) {
key.set(UTF8, value, null, null);
Item result = get(key);
if (result == null) {
pool.putByte(UTF8).putUTF8(value);
result = new Item(index++, key);
put(result);
}
return result.index;
}
/**
* Adds a class reference to the constant pool of the class being build. Does
* nothing if the constant pool already contains a similar item. <i>This
* method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.</i>
*
* @param value the internal name of the class.
* @return the index of a new or already existing class reference item.
*/
public int newClass (final String value) {
return newClassItem(value).index;
}
/**
* Adds a class reference to the constant pool of the class being build. Does
* nothing if the constant pool already contains a similar item. <i>This
* method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.</i>
*
* @param value the internal name of the class.
* @return a new or already existing class reference item.
*/
private Item newClassItem (final String value) {
key2.set(CLASS, value, null, null);
Item result = get(key2);
if (result == null) {
pool.put12(CLASS, newUTF8(value));
result = new Item(index++, key2);
put(result);
}
return result;
}
/**
* Adds a field reference to the constant pool of the class being build. Does
* nothing if the constant pool already contains a similar item. <i>This
* method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.</i>
*
* @param owner the internal name of the field's owner class.
* @param name the field's name.
* @param desc the field's descriptor.
* @return the index of a new or already existing field reference item.
*/
public int newField (
final String owner,
final String name,
final String desc)
{
key3.set(FIELD, owner, name, desc);
Item result = get(key3);
if (result == null) {
put122(FIELD, newClass(owner), newNameType(name, desc));
result = new Item(index++, key3);
put(result);
}
return result.index;
}
/**
* Adds a method reference to the constant pool of the class being build. Does
* nothing if the constant pool already contains a similar item.
*
* @param owner the internal name of the method's owner class.
* @param name the method's name.
* @param desc the method's descriptor.
* @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
* @return a new or already existing method reference item.
*/
Item newMethodItem (
final String owner,
final String name,
final String desc,
final boolean itf)
{
key3.set(itf ? IMETH : METH, owner, name, desc);
Item result = get(key3);
if (result == null) {
put122(itf ? IMETH : METH, newClass(owner), newNameType(name, desc));
result = new Item(index++, key3);
put(result);
}
return result;
}
/**
* Adds a method reference to the constant pool of the class being build. Does
* nothing if the constant pool already contains a similar item. <i>This
* method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.</i>
*
* @param owner the internal name of the method's owner class.
* @param name the method's name.
* @param desc the method's descriptor.
* @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
* @return the index of a new or already existing method reference item.
*/
public int newMethod (
final String owner,
final String name,
final String desc,
final boolean itf)
{
return newMethodItem(owner, name, desc, itf).index;
}
/**
* Adds an integer to the constant pool of the class being build. Does nothing
* if the constant pool already contains a similar item.
*
* @param value the int value.
* @return a new or already existing int item.
*/
private Item newInteger (final int value) {
key.set(value);
Item result = get(key);
if (result == null) {
pool.putByte(INT).putInt(value);
result = new Item(index++, key);
put(result);
}
return result;
}
/**
* Adds a float to the constant pool of the class being build. Does nothing if
* the constant pool already contains a similar item.
*
* @param value the float value.
* @return a new or already existing float item.
*/
private Item newFloat (final float value) {
key.set(value);
Item result = get(key);
if (result == null) {
pool.putByte(FLOAT).putInt(Float.floatToIntBits(value));
result = new Item(index++, key);
put(result);
}
return result;
}
/**
* Adds a long to the constant pool of the class being build. Does nothing if
* the constant pool already contains a similar item.
*
* @param value the long value.
* @return a new or already existing long item.
*/
private Item newLong (final long value) {
key.set(value);
Item result = get(key);
if (result == null) {
pool.putByte(LONG).putLong(value);
result = new Item(index, key);
put(result);
index += 2;
}
return result;
}
/**
* Adds a double to the constant pool of the class being build. Does nothing
* if the constant pool already contains a similar item.
*
* @param value the double value.
* @return a new or already existing double item.
*/
private Item newDouble (final double value) {
key.set(value);
Item result = get(key);
if (result == null) {
pool.putByte(DOUBLE).putLong(Double.doubleToLongBits(value));
result = new Item(index, key);
put(result);
index += 2;
}
return result;
}
/**
* Adds a string to the constant pool of the class being build. Does nothing
* if the constant pool already contains a similar item.
*
* @param value the String value.
* @return a new or already existing string item.
*/
private Item newString (final String value) {
key2.set(STR, value, null, null);
Item result = get(key2);
if (result == null) {
pool.put12(STR, newUTF8(value));
result = new Item(index++, key2);
put(result);
}
return result;
}
/**
* Adds a name and type to the constant pool of the class being build. Does
* nothing if the constant pool already contains a similar item. <i>This
* method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.</i>
*
* @param name a name.
* @param desc a type descriptor.
* @return the index of a new or already existing name and type item.
*/
public int newNameType (final String name, final String desc) {
key2.set(NAME_TYPE, name, desc, null);
Item result = get(key2);
if (result == null) {
put122(NAME_TYPE, newUTF8(name), newUTF8(desc));
result = new Item(index++, key2);
put(result);
}
return result.index;
}
/**
* Returns the constant pool's hash table item which is equal to the given
* item.
*
* @param key a constant pool item.
* @return the constant pool's hash table item which is equal to the given
* item, or <tt>null</tt> if there is no such item.
*/
private Item get (final Item key) {
int h = key.hashCode;
Item i = items[h % items.length];
while (i != null) {
if (i.hashCode == h && key.isEqualTo(i)) {
return i;
}
i = i.next;
}
return null;
}
/**
* Puts the given item in the constant pool's hash table. The hash table
* <i>must</i> not already contains this item.
*
* @param i the item to be added to the constant pool's hash table.
*/
private void put (final Item i) {
if (index > threshold) {
Item[] newItems = new Item[items.length * 2 + 1];
for (int l = items.length - 1; l >= 0; --l) {
Item j = items[l];
while (j != null) {
int index = j.hashCode % newItems.length;
Item k = j.next;
j.next = newItems[index];
newItems[index] = j;
j = k;
}
}
items = newItems;
threshold = (int)(items.length * 0.75);
}
int index = i.hashCode % items.length;
i.next = items[index];
items[index] = i;
}
/**
* Puts one byte and two shorts into the constant pool.
*
* @param b a byte.
* @param s1 a short.
* @param s2 another short.
*/
private void put122 (final int b, final int s1, final int s2) {
pool.put12(b, s1).putShort(s2);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -