public static Method getImplementationMethod(SerializedLambda serializedLambda) throws NoSuchMethodException, ClassNotFoundException { return getMethod(serializedLambda.getImplClass(), serializedLambda.getImplMethodName()); }
String className = serializedLambda.getImplClass(); String methodName = serializedLambda.getImplMethodName(); String methodSig = serializedLambda.getImplMethodSignature();
try { functionalMethod = getMethod(lambda.getClass(), serializedLambda.getFunctionalInterfaceMethodName()); int implMethodKind = serializedLambda.getImplMethodKind(); if (serializedLambda.getImplMethodName().startsWith("lambda$")) { kind = Kind.ANONYMOUS_METHOD_REFERENCE; } else { if (serializedLambda.getCapturedArgCount() > 0) { kind = Kind.SPECIFIC_INSTANCE_METHOD_REFERENCE; } else {
public static String fnToFieldName(Fn fn) { try { Method method = fn.getClass().getDeclaredMethod("writeReplace"); method.setAccessible(Boolean.TRUE); SerializedLambda serializedLambda = (SerializedLambda) method.invoke(fn); String getter = serializedLambda.getImplMethodName(); if (GET_PATTERN.matcher(getter).matches()) { getter = getter.substring(3); } else if (IS_PATTERN.matcher(getter).matches()) { getter = getter.substring(2); } return Introspector.decapitalize(getter); } catch (ReflectiveOperationException e) { throw new ReflectionOperationException(e); } } }
default Class<?> getContainingClass() { try { String className = serialized().getImplClass().replaceAll("/", "."); return Class.forName(className); } catch (Exception e) { throw new RuntimeException(e); } }
default String getResultDescription() { SerializedLambda lambda = asSerializedLambda(); MethodType lambdaMethodType = MethodType.fromMethodDescriptorString(lambda.getImplMethodSignature(), getClass().getClassLoader()); String resultType = lambdaMethodType.returnType().getSimpleName(); if (! lambda.getImplMethodName().startsWith("lambda$")) { return lambda.getImplMethodName() + " (" + withPrefixedArticle(resultType) + ")"; } return resultType; }
switch ( serialized.getImplMethodKind() ) impl, serialized.getImplMethodName(), MethodType.fromMethodDescriptorString( serialized.getImplMethodSignature(), impl.getClassLoader() ) ); case MethodHandleInfo.REF_invokeVirtual: return lookup.findVirtual( impl, serialized.getImplMethodName(), MethodType.fromMethodDescriptorString( serialized.getImplMethodSignature(), impl.getClassLoader() ) ); default: throw new UnsupportedOperationException( "only static and virtual methods supported" );
/** * Returns a String of the form (PRIMITIVE|CLASS|ARRAY)* * <p> * PRIMITIVE = [ZBCSIJFD] * <p> * CLASS = L[^;]+; * <p> * ARRAY = \[+(PRIMITIVE|CLASS) */ private static String getParameterTypesString(SerializedLambda actualLambda) { String methodSignature = actualLambda.getInstantiatedMethodType(); Matcher matcher = PARAMETER_LIST_PATTERN.matcher(methodSignature); matcher.find(); return matcher.group("parameters"); }
private static MethodType extractChecked(Serializable serializable) throws IllegalArgumentException, TypeNotPresentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, SecurityException{ Method method = serializable.getClass().getDeclaredMethod("writeReplace"); method.setAccessible(true); MethodType type = MethodType.fromMethodDescriptorString( ((SerializedLambda) method.invoke(serializable)).getImplMethodSignature(), serializable.getClass().getClassLoader()); return type; } }
Parameter[] parameters = lambdaMethod( serialized ).getParameters(); int bound; switch ( serialized.getImplMethodKind() ) bound = serialized.getCapturedArgCount(); break; case REF_invokeSpecial: bound = serialized.getCapturedArgCount() - 1; break; default: throw new IllegalArgumentException( "Unsupported method kind: " + serialized.getImplMethodKind() );
@Override public int size() { return actualLambda.getCapturedArgCount(); } };
public static String fnToFieldName(Fn fn) { try { Method method = fn.getClass().getDeclaredMethod("writeReplace"); method.setAccessible(Boolean.TRUE); SerializedLambda serializedLambda = (SerializedLambda) method.invoke(fn); String getter = serializedLambda.getImplMethodName(); if (GET_PATTERN.matcher(getter).matches()) { getter = getter.substring(3); } else if (IS_PATTERN.matcher(getter).matches()) { getter = getter.substring(2); } return Introspector.decapitalize(getter); } catch (ReflectiveOperationException e) { throw new ReflectionOperationException(e); } } }
private static Class<?> lambdaClass( SerializedLambda serialized ) { try { return Class.forName( serialized.getImplClass().replaceAll( "/", "." ) ); } catch ( ClassNotFoundException e ) { throw new IllegalStateException( e ); } }
static Method lambdaToMethod(Serializable lambda) { for(Class<?> cl=lambda.getClass(); cl!=null; cl=cl.getSuperclass()) try { Method m=cl.getDeclaredMethod("writeReplace"); m.setAccessible(true); try { SerializedLambda sl=(SerializedLambda)m.invoke(lambda); return LambdaToMethod.class.getDeclaredMethod(sl.getImplMethodName(), MethodType.fromMethodDescriptorString(sl.getImplMethodSignature(), LambdaToMethod.class.getClassLoader()).parameterArray()); } catch(ReflectiveOperationException ex) { throw new RuntimeException(ex); } } catch(NoSuchMethodException ex){} throw new AssertionError(); } public static void main(String[] args) { legacyCaller("a string", lambdaToMethod((Consumer<String>&Serializable) s -> System.out.println("first lambda called with "+s))); legacyCaller("a string", lambdaToMethod((Consumer<String>&Serializable) s -> System.out.println("second lambda called with "+s))); }
/** * Extracts the actual types of all lambda generic parameters. * Example: for "BiConsumer<String, Integer>", this method returns ["java.lang.String", "java.lang.Integer"]. */ private static String[] getGenericTypeStrings(SerializableLambda lambda) { // The only portable way to get the actual lambda generic parameters can be done using SerializedLambda. SerializedLambda sl = getSerializedLambda(lambda); String lambdaMethodType = sl.getInstantiatedMethodType(); Matcher m = LAMBDA_INSTANCE_METHOD_TYPE.matcher(lambdaMethodType); List<String> results = new ArrayList<>(); while (m.find()) { results.add(m.group().substring(1).replace("/", ".")); } return results.toArray(new String[0]); }
public static String getLambdaFieldName(SerializedLambda serializedLambda) { String name = CACHE_LAMBDA_NAME.get(serializedLambda); if (null != name) { return name; } String className = serializedLambda.getImplClass().replace("/", "."); String methodName = serializedLambda.getImplMethodName(); String fieldName = methodToFieldName(methodName); try { Field field = Class.forName(className).getDeclaredField(fieldName); name = field.getName(); CACHE_LAMBDA_NAME.put(serializedLambda, name); return name; } catch (NoSuchFieldException | ClassNotFoundException e) { throw new RuntimeException(e); } }
default Method method() { SerializedLambda lambda = serialized(); Class<?> containingClass = getContainingClass(); return asList(containingClass.getDeclaredMethods()) .stream() .filter(method -> Objects.equals(method.getName(), lambda.getImplMethodName())) .findFirst() .orElseThrow(UnableToGuessMethodException::new); }
String className = serializedLambda.getImplClass(); String methodName = serializedLambda.getImplMethodName(); String methodSig = serializedLambda.getImplMethodSignature();
default Class<?> implementationClass(SerializedLambda serializedLambda) { try { final String className = serializedLambda.getImplClass().replaceAll("/", "."); return Class.forName(className); } catch (Exception e) { throw new RuntimeException(e); } }
public static void main(String[] args) { String mt = extractConsumer((Lambda t) -> t.toString()).get().getInstantiatedMethodType(); System.out.println(mt); System.out.println(MethodType.fromMethodDescriptorString(mt, Thread.currentThread().getContextClassLoader()).parameterType(0)); }