📄 descriptor.java
字号:
public static CtClass[] getParameterTypes(String desc, ClassPool cp) throws NotFoundException { if (desc.charAt(0) != '(') return null; else { int num = numOfParameters(desc); CtClass[] args = new CtClass[num]; int n = 0; int i = 1; do { i = toCtClass(cp, desc, i, args, n++); } while (i > 0); return args; } } /** * Returns true if the list of the parameter types of desc1 is equal to * that of desc2. * For example, "(II)V" and "(II)I" are equal. */ public static boolean eqParamTypes(String desc1, String desc2) { if (desc1.charAt(0) != '(') return false; for (int i = 0; true; ++i) { char c = desc1.charAt(i); if (c != desc2.charAt(i)) return false; if (c == ')') return true; } } /** * Returns the signature of the given descriptor. The signature does * not include the return type. For example, the signature of "(I)V" * is "(I)". */ public static String getParamDescriptor(String decl) { return decl.substring(0, decl.indexOf(')') + 1); } /** * Returns the <code>CtClass</code> object representing the return * type specified by the given descriptor. * * @param desc descriptor * @param cp the class pool used for obtaining * a <code>CtClass</code> object. */ public static CtClass getReturnType(String desc, ClassPool cp) throws NotFoundException { int i = desc.indexOf(')'); if (i < 0) return null; else { CtClass[] type = new CtClass[1]; toCtClass(cp, desc, i + 1, type, 0); return type[0]; } } /** * Returns the number of the prameters included in the given * descriptor. * * @param desc descriptor */ public static int numOfParameters(String desc) { int n = 0; int i = 1; for (;;) { char c = desc.charAt(i); if (c == ')') break; while (c == '[') c = desc.charAt(++i); if (c == 'L') { i = desc.indexOf(';', i) + 1; if (i <= 0) throw new IndexOutOfBoundsException("bad descriptor"); } else ++i; ++n; } return n; } /** * Returns a <code>CtClass</code> object representing the type * specified by the given descriptor. * * <p>This method works even if the package-class separator is * not <code>/</code> but <code>.</code> (period). For example, * it accepts <code>Ljava.lang.Object;</code> * as well as <code>Ljava/lang/Object;</code>. * * @param desc descriptor * @param cp the class pool used for obtaining * a <code>CtClass</code> object. */ public static CtClass toCtClass(String desc, ClassPool cp) throws NotFoundException { CtClass[] clazz = new CtClass[1]; int res = toCtClass(cp, desc, 0, clazz, 0); if (res >= 0) return clazz[0]; else { // maybe, you forgot to surround the class name with // L and ;. It violates the protocol, but I'm tolerant... return cp.get(desc.replace('/', '.')); } } private static int toCtClass(ClassPool cp, String desc, int i, CtClass[] args, int n) throws NotFoundException { int i2; String name; int arrayDim = 0; char c = desc.charAt(i); while (c == '[') { ++arrayDim; c = desc.charAt(++i); } if (c == 'L') { i2 = desc.indexOf(';', ++i); name = desc.substring(i, i2++).replace('/', '.'); } else { CtClass type = toPrimitiveClass(c); if (type == null) return -1; // error i2 = i + 1; if (arrayDim == 0) { args[n] = type; return i2; // neither an array type or a class type } else name = type.getName(); } if (arrayDim > 0) { StringBuffer sbuf = new StringBuffer(name); while (arrayDim-- > 0) sbuf.append("[]"); name = sbuf.toString(); } args[n] = cp.get(name); return i2; } private static CtClass toPrimitiveClass(char c) { CtClass type = null; switch (c) { case 'Z' : type = CtClass.booleanType; break; case 'C' : type = CtClass.charType; break; case 'B' : type = CtClass.byteType; break; case 'S' : type = CtClass.shortType; break; case 'I' : type = CtClass.intType; break; case 'J' : type = CtClass.longType; break; case 'F' : type = CtClass.floatType; break; case 'D' : type = CtClass.doubleType; break; case 'V' : type = CtClass.voidType; break; } return type; } /** * Computes the dimension of the array represented by the given * descriptor. For example, if the descriptor is <code>"[[I"</code>, * then this method returns 2. * * @param desc the descriptor. * @return 0 if the descriptor does not represent an array type. */ public static int arrayDimension(String desc) { int dim = 0; while (desc.charAt(dim) == '[') ++dim; return dim; } /** * Returns the descriptor of the type of the array component. * For example, if the given descriptor is * <code>"[[Ljava/lang/String;"</code> and the given dimension is 2, * then this method returns <code>"Ljava/lang/String;"</code>. * * @param desc the descriptor. * @param dim the array dimension. */ public static String toArrayComponent(String desc, int dim) { return desc.substring(dim); } /** * Computes the data size specified by the given descriptor. * For example, if the descriptor is "D", this method returns 2. * * <p>If the descriptor represents a method type, this method returns * (the size of the returned value) - (the sum of the data sizes * of all the parameters). For example, if the descriptor is * <code>"(I)D"</code>, then this method returns 1 (= 2 - 1). * * @param desc descriptor */ public static int dataSize(String desc) { return dataSize(desc, true); } /** * Computes the data size of parameters. * If one of the parameters is double type, the size of that parameter * is 2 words. For example, if the given descriptor is * <code>"(IJ)D"</code>, then this method returns 3. The size of the * return type is not computed. * * @param desc a method descriptor. */ public static int paramSize(String desc) { return -dataSize(desc, false); } private static int dataSize(String desc, boolean withRet) { int n = 0; char c = desc.charAt(0); if (c == '(') { int i = 1; for (;;) { c = desc.charAt(i); if (c == ')') { c = desc.charAt(i + 1); break; } boolean array = false; while (c == '[') { array = true; c = desc.charAt(++i); } if (c == 'L') { i = desc.indexOf(';', i) + 1; if (i <= 0) throw new IndexOutOfBoundsException("bad descriptor"); } else ++i; if (!array && (c == 'J' || c == 'D')) n -= 2; else --n; } } if (withRet) if (c == 'J' || c == 'D') n += 2; else if (c != 'V') ++n; return n; } /** * An Iterator over a descriptor. */ public static class Iterator { private String desc; private int index, curPos; private boolean param; /** * Constructs an iterator. * * @param s descriptor. */ public Iterator(String s) { desc = s; index = curPos = 0; param = false; } /** * Returns true if the iteration has more elements. */ public boolean hasNext() { return index < desc.length(); } /** * Returns true if the current element is a parameter type. */ public boolean isParameter() { return param; } /** * Returns the first character of the current element. */ public char currentChar() { return desc.charAt(curPos); } /** * Returns true if the current element is double or long type. */ public boolean is2byte() { char c = currentChar(); return c == 'D' || c == 'J'; } /** * Returns the position of the next type character. * That type character becomes a new current element. */ public int next() { int nextPos = index; char c = desc.charAt(nextPos); if (c == '(') { ++index; c = desc.charAt(++nextPos); param = true; } if (c == ')') { ++index; c = desc.charAt(++nextPos); param = false; } while (c == '[') c = desc.charAt(++nextPos); if (c == 'L') { nextPos = desc.indexOf(';', nextPos) + 1; if (nextPos <= 0) throw new IndexOutOfBoundsException("bad descriptor"); } else ++nextPos; curPos = index; index = nextPos; return curPos; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -