/** Return the declared type of this member, which must be a method or constructor. */ public MethodType getMethodType() { if (type == null) { expandFromVM(); if (type == null) return null; } if (!isInvocable()) throw newIllegalArgumentException("not invocable, no method type"); if (type instanceof MethodType) { return (MethodType) type; } if (type instanceof String) { String sig = (String) type; MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader()); this.type = res; return res; } if (type instanceof Object[]) { Object[] typeInfo = (Object[]) type; Class<?>[] ptypes = (Class<?>[]) typeInfo[1]; Class<?> rtype = (Class<?>) typeInfo[0]; MethodType res = MethodType.methodType(rtype, ptypes); this.type = res; return res; } throw new InternalError("bad method type " + type); }
/** * Sole factory method to find or create an interned method type. * * @param rtype desired return type * @param ptypes desired parameter types * @param trusted whether the ptypes can be used without cloning * @return the unique method type of the desired structure */ /*trusted*/ static MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) { if (ptypes.length == 0) { ptypes = NO_PTYPES; trusted = true; } MethodType mt1 = new MethodType(rtype, ptypes); MethodType mt0; synchronized (internTable) { mt0 = internTable.get(mt1); if (mt0 != null) return mt0; } if (!trusted) // defensively copy the array passed in by the user mt1 = new MethodType(rtype, ptypes.clone()); // promote the object to the Real Thing, and reprobe MethodTypeForm form = MethodTypeForm.findForm(mt1); mt1.form = form; if (form.erasedType == mt1) { // This is a principal (erased) type; show it to the JVM. MethodHandleNatives.init(mt1); } synchronized (internTable) { mt0 = internTable.get(mt1); if (mt0 != null) return mt0; internTable.put(mt1, mt1); } return mt1; }
/*non-public*/ boolean isConvertibleTo(MethodType newType) { if (!canConvert(returnType(), newType.returnType())) return false; int argc = parameterCount(); if (argc != newType.parameterCount()) return false; for (int i = 0; i < argc; i++) { if (!canConvert(newType.parameterType(i), parameterType(i))) return false; } return true; }
private static MethodType unwrapWithNoPrims(MethodType wt) { assert (!wt.hasPrimitives()); MethodType uwt = wt.wrapAlt; if (uwt == null) { // fill in lazily uwt = MethodTypeForm.canonicalize(wt, MethodTypeForm.UNWRAP, MethodTypeForm.UNWRAP); if (uwt == null) uwt = wt; // type has no wrappers or prims at all wt.wrapAlt = uwt; } return uwt; }
private static MethodType wrapWithPrims(MethodType pt) { assert (pt.hasPrimitives()); MethodType wt = pt.wrapAlt; if (wt == null) { // fill in lazily wt = MethodTypeForm.canonicalize(pt, MethodTypeForm.WRAP, MethodTypeForm.WRAP); assert (wt != null); pt.wrapAlt = wt; } return wt; }
/** * Return the declared type of this member, which must be a field or type. If it is a type member, * that type itself is returned. */ public Class<?> getFieldType() { if (type == null) { expandFromVM(); if (type == null) return null; } if (isInvocable()) throw newIllegalArgumentException("not a field or nested class, no simple type"); if (type instanceof Class<?>) { return (Class<?>) type; } if (type instanceof String) { String sig = (String) type; MethodType mtype = MethodType.fromMethodDescriptorString("()" + sig, getClassLoader()); Class<?> res = mtype.returnType(); this.type = res; return res; } throw new InternalError("bad field type " + type); }
/** * Return the actual type under which this method or constructor must be invoked. For non-static * methods or constructors, this is the type with a leading parameter, a reference to declaring * class. For static methods, it is the same as the declared type. */ public MethodType getInvocationType() { MethodType itype = getMethodType(); if (!isStatic()) itype = itype.insertParameterTypes(0, clazz); return itype; }