@@ -130,12 +130,14 @@ public static boolean isLambdaName(String name) {
130130 }
131131
132132 /**
133- * Generates a signature for a given lambda type by hashing its composing parts. The signature
134- * is generated based on the methods invoked in the lambda's bytecode, the constructor parameter
135- * types, and the interfaces implemented by the lambda. Returns {@code null} if the lambda type
136- * does not have any invoked methods.
133+ * Generates a signature for a given type by hashing its composing parts. The signature is
134+ * generated based on the methods invoked in the bytecode of a public non-bridge method, the
135+ * constructor parameter types, and the interfaces implemented by the type. Returns {@code null}
136+ * if the selected declared method does not invoke any other method. The procedure should
137+ * generate reasonable signatures for lambda proxy types, but it may fail to do so for general
138+ * hidden classes.
137139 * <p>
138- * Starting from JDK17, the lambda classes can have additional interfaces that lambda should
140+ * Starting from JDK17, lambda classes can have additional interfaces that lambda should
139141 * implement. This further means that lambda can have more than one public method (public and
140142 * not bridge).
141143 * <p>
@@ -144,33 +146,31 @@ public static boolean isLambdaName(String name) {
144146 * parameters are Object types) and serves as a wrapper that casts parameters to specialized
145147 * types and calls an original method.
146148 *
147- * @param lambdaType the lambda type to generate a signature for
148- * @return a 32-character hexadecimal string representing the lambda's signature or {@code null}
149- * if the lambda type does not have any invoked methods
149+ * @param type the type to generate a signature for
150+ * @return a 32-character hexadecimal string representing the type signature or {@code null} if
151+ * the selected declared method does not have any invokes
150152 */
151- public static String getSignature (ResolvedJavaType lambdaType ) {
152- ResolvedJavaMethod [] lambdaProxyMethods = Arrays .stream (lambdaType .getDeclaredMethods (false )).filter (m -> !m .isBridge () && m .isPublic ()).toArray (ResolvedJavaMethod []::new );
153+ public static String getSignature (ResolvedJavaType type ) {
153154 /*
154155 * Take only the first method to find invoked methods, because the result would be the same
155- * for all other methods.
156+ * for all other methods (if it is a lambda type) .
156157 */
157- List <JavaMethod > invokedMethods = findInvokedMethods ( lambdaProxyMethods [ 0 ] );
158+ List <JavaMethod > invokedMethods = Arrays . stream ( type . getDeclaredMethods ( false )). filter ( m -> ! m . isBridge () && m . isPublic ()). findFirst (). map ( LambdaUtils :: findInvokedMethods ). orElse ( List . of () );
158159 if (invokedMethods .isEmpty ()) {
159160 return null ;
160161 }
161-
162- /* Generate lambda signature by hashing its composing parts. */
162+ /* Generate type signature by hashing its composing parts. */
163163 StringBuilder sb = new StringBuilder ();
164164 /* Append invoked methods. */
165165 for (JavaMethod method : invokedMethods ) {
166166 sb .append (method .format ("%H.%n(%P)%R" ));
167167 }
168168 /* Append constructor parameter types. */
169- for (JavaMethod ctor : lambdaType .getDeclaredConstructors ()) {
169+ for (JavaMethod ctor : type .getDeclaredConstructors ()) {
170170 sb .append (ctor .format ("%P" ));
171171 }
172172 /* Append implemented interfaces. */
173- for (ResolvedJavaType iface : lambdaType .getInterfaces ()) {
173+ for (ResolvedJavaType iface : type .getInterfaces ()) {
174174 sb .append (iface .toJavaName ());
175175 }
176176 String signature = Digest .digestAsHex (sb .toString ());
0 commit comments