All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tangosol.internal.util.invoke.lambda.MethodReferenceIdentity Maven / Gradle / Ivy

There is a newer version: 24.09
Show newest version
/*
 * Copyright (c) 2000, 2020, Oracle and/or its affiliates.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * http://oss.oracle.com/licenses/upl.
 */
package com.tangosol.internal.util.invoke.lambda;

import com.tangosol.dev.assembler.Method;

import com.tangosol.util.Base;

import java.lang.invoke.MethodHandleInfo;
import java.lang.invoke.SerializedLambda;

/**
 * {@code MethodReferenceIdentity} is a specialization of {@link LambdaIdentity}
 * that is used to identify method reference-based lambdas.
 * 

* Unlike {@link AnonymousLambdaIdentity}, which can rely on uniqueness based * upon three characteristics (capturing class, method name, and MD5(capturing class), * method references must employ greater scrutiny in deriving uniqueness as the * SAM implementations must also be taken into consideration. *

* Consider the two method references below which should not be deemed the same: *


 *     Supplier         s = T::new;
 *     Function s = T::new;
 * 
* * @author hr/as 2015.06.01 * @since 12.2.1 * * @see AnonymousLambdaIdentity */ public class MethodReferenceIdentity extends LambdaIdentity { // ----- constructors ----------------------------------------------- /** * Default constructor; used for deserialization. */ public MethodReferenceIdentity() { } /** * Construct a MethodReferenceIdentity that represents the provided * {@link SerializedLambda function metadata}. * * @param lambdaMetadata function metadata * @param loader ClassLoader used to load the capturing class file */ public MethodReferenceIdentity(SerializedLambda lambdaMetadata, ClassLoader loader) { super(getInvokeClass(lambdaMetadata), lambdaMetadata.getImplMethodName(), createVersion(lambdaMetadata)); } // ----- private constants ---------------------------------------------- /** * Return the internal class name for the target of the invoke instruction. * * @param lambdaMetadata function metadata * * @return the internal class name for the target of the invoke instruction */ private static String getInvokeClass(SerializedLambda lambdaMetadata) { int nInvokeKind = lambdaMetadata.getImplMethodKind(); switch (nInvokeKind) { case MethodHandleInfo.REF_invokeInterface: case MethodHandleInfo.REF_invokeVirtual: { String sDestType = Method.toTypes(lambdaMetadata.getInstantiatedMethodType())[1]; return sDestType.charAt(0) == 'L' ? sDestType.substring(1, sDestType.length() - 1) : sDestType; } default: return lambdaMetadata.getImplClass(); } } /** * Create unique version string for the specified lambda. * * @param lambdaMetadata function metadata * * @return a unique version string for the specified lambda */ private static String createVersion(SerializedLambda lambdaMetadata) { String sReferredMethod = String.format(METHOD_REF_FORMAT, getInvokeClass(lambdaMetadata), lambdaMetadata.getImplMethodName(), lambdaMetadata.getImplMethodSignature()); String sSAMImpl = String.format(METHOD_REF_FORMAT, lambdaMetadata.getFunctionalInterfaceClass(), lambdaMetadata.getFunctionalInterfaceMethodName(), lambdaMetadata.getFunctionalInterfaceMethodSignature()); return Base.toHex(md5(sReferredMethod + "$" + sSAMImpl)); } /** * String format used to describe the method reference and SAM. */ private static final String METHOD_REF_FORMAT = "%s.%s:%s"; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy