@Test public void testMethodType() throws Exception { assertThat(JavaType.METHOD_TYPE.getTypeStub().getName(), is("java.lang.invoke.MethodType")); assertThat( JavaType.METHOD_TYPE.getTypeStub().getModifiers(), is(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL)); assertThat( JavaType.METHOD_TYPE.getTypeStub().getSuperClass(), is(TypeDescription.Generic.OBJECT)); assertThat(JavaType.METHOD_TYPE.getTypeStub().getInterfaces().size(), is(1)); assertThat( JavaType.METHOD_TYPE .getTypeStub() .getInterfaces() .contains( new TypeDescription.Generic.OfNonGenericType.ForLoadedType(Serializable.class)), is(true)); }
@Test @JavaVersionRule.Enforce(7) public void testJava7Types() throws Exception { assertThat(JavaType.METHOD_HANDLE.load(), notNullValue(Class.class)); assertThat(JavaType.METHOD_TYPE.load(), notNullValue(Class.class)); assertThat(JavaType.METHOD_HANDLES_LOOKUP.load(), notNullValue(Class.class)); assertThat(JavaType.CALL_SITE.load(), notNullValue(Class.class)); }
/** * Returns a method type representation of a loaded {@code MethodType} object. * * @param methodType A method type object to represent as a {@link JavaInstance}. * @return The method type represented as a {@code JavaInstance}. */ public static MethodType of(Object methodType) { if (!JavaType.METHOD_TYPE.getTypeStub().isInstance(methodType)) { throw new IllegalArgumentException("Excpected method type object: " + methodType); } return of( (Class<?>) RETURN_TYPE.invoke(methodType), (Class<?>[]) PARAMETER_ARRAY.invoke(methodType)); }
/* * Locates the Java methods for calling methods on {@code MethodType} instances, if those are available. */ static { JavaMethod returnType, parameterArray; try { Class<?> methodType = JavaType.METHOD_TYPE.load(); returnType = new JavaMethod.ForLoadedMethod(methodType.getDeclaredMethod("returnType")); parameterArray = new JavaMethod.ForLoadedMethod(methodType.getDeclaredMethod("parameterArray")); } catch (Exception ignored) { returnType = JavaMethod.ForUnavailableMethod.INSTANCE; parameterArray = JavaMethod.ForUnavailableMethod.INSTANCE; } RETURN_TYPE = returnType; PARAMETER_ARRAY = parameterArray; }
/* * Locates the Java methods for calling methods on {@code MethodHandle} instances, if those are available. */ static { JavaMethod revealDirect, newMethodHandleInfo, lookup, getName, getDeclaringClass, getReferenceKind, getMethodType, returnType, parameterArray; try { Class<?> methodHandlesLookup = JavaType.METHOD_HANDLES_LOOKUP.load(); try { revealDirect = new JavaMethod.ForLoadedMethod( methodHandlesLookup.getDeclaredMethod( "revealDirect", JavaType.METHOD_HANDLE.load())); } catch (Exception ignored) { revealDirect = JavaMethod.ForUnavailableMethod.INSTANCE; } Class<?> methodHandles = Class.forName("java.lang.invoke.MethodHandles"); lookup = new JavaMethod.ForLoadedMethod(methodHandles.getDeclaredMethod("publicLookup")); Class<?> methodHandleInfo = Class.forName("java.lang.invoke.MethodHandleInfo"); if (revealDirect.isInvokable()) { newMethodHandleInfo = JavaMethod.ForUnavailableMethod.INSTANCE; } else { Constructor<?> newMethodHandleInfoConstructor = methodHandleInfo.getDeclaredConstructor(JavaType.METHOD_HANDLE.load()); newMethodHandleInfoConstructor.setAccessible(true); newMethodHandleInfo = new JavaMethod.ForLoadedConstructor(newMethodHandleInfoConstructor); } Method getNameMethod = methodHandleInfo.getDeclaredMethod("getName"); Method getDeclaringClassMethod = methodHandleInfo.getDeclaredMethod("getDeclaringClass"); Method getReferenceKindMethod = methodHandleInfo.getDeclaredMethod("getReferenceKind"); Method getMethodTypeMethod = methodHandleInfo.getDeclaredMethod("getMethodType"); getName = new JavaMethod.ForLoadedMethod(getNameMethod); getDeclaringClass = new JavaMethod.ForLoadedMethod(getDeclaringClassMethod); getReferenceKind = new JavaMethod.ForLoadedMethod(getReferenceKindMethod); getMethodType = new JavaMethod.ForLoadedMethod(getMethodTypeMethod); if (!revealDirect.isInvokable()) { getNameMethod.setAccessible(true); getDeclaringClassMethod.setAccessible(true); getReferenceKindMethod.setAccessible(true); getMethodTypeMethod.setAccessible(true); } Class<?> methodType = JavaType.METHOD_TYPE.load(); returnType = new JavaMethod.ForLoadedMethod(methodType.getDeclaredMethod("returnType")); parameterArray = new JavaMethod.ForLoadedMethod(methodType.getDeclaredMethod("parameterArray")); } catch (Exception ignored) { revealDirect = JavaMethod.ForUnavailableMethod.INSTANCE; newMethodHandleInfo = JavaMethod.ForUnavailableMethod.INSTANCE; lookup = JavaMethod.ForUnavailableMethod.INSTANCE; getName = JavaMethod.ForUnavailableMethod.INSTANCE; getDeclaringClass = JavaMethod.ForUnavailableMethod.INSTANCE; getReferenceKind = JavaMethod.ForUnavailableMethod.INSTANCE; getMethodType = JavaMethod.ForUnavailableMethod.INSTANCE; returnType = JavaMethod.ForUnavailableMethod.INSTANCE; parameterArray = JavaMethod.ForUnavailableMethod.INSTANCE; } REVEAL_DIRECT = revealDirect; NEW_METHOD_HANDLE_INFO = newMethodHandleInfo; LOOKUP = lookup; GET_NAME = getName; GET_DECLARING_CLASS = getDeclaringClass; GET_REFERENCE_KIND = getReferenceKind; GET_METHOD_TYPE = getMethodType; RETURN_TYPE = returnType; PARAMETER_ARRAY = parameterArray; }
@Override public TypeDescription getInstanceType() { return JavaType.METHOD_TYPE.getTypeStub(); }