From cf0c849ce603b3367289f6c995cae2035d7bf2d9 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 27 Apr 2019 10:13:56 +0800 Subject: [PATCH] Add `addLambdaMemberFilter` method --- .../net/jodah/typetools/TypeResolver.java | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/jodah/typetools/TypeResolver.java b/src/main/java/net/jodah/typetools/TypeResolver.java index e65dd4f..c18ace0 100644 --- a/src/main/java/net/jodah/typetools/TypeResolver.java +++ b/src/main/java/net/jodah/typetools/TypeResolver.java @@ -31,11 +31,8 @@ import java.lang.reflect.WildcardType; import java.security.AccessController; import java.security.PrivilegedExceptionAction; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.WeakHashMap; +import java.util.*; +import java.util.function.Predicate; import sun.misc.Unsafe; @@ -57,6 +54,7 @@ public final class TypeResolver { private static final Map OBJECT_METHODS = new HashMap(); private static final Map, Class> PRIMITIVE_WRAPPERS; private static final Double JAVA_VERSION; + private static final List> lambdaMemberFilters = new ArrayList<>(); static { JAVA_VERSION = Double.parseDouble(System.getProperty("java.specification.version", "0")); @@ -373,6 +371,17 @@ public static Class resolveRawClass(Type genericType, Class subType) { return resolveRawClass(genericType, subType, null); } + /** + * Using some low-level instruction technology may add some members into the constant pool. The generated members + * could make {@link TypeResolver} to return a wrong type. To avoid this, use {@code addLambdaMemberFilter} to + * add a custom lambda member filter to skip wrong members. + * + * @param lambdaMemberFilter to add + */ + public static synchronized void addLambdaMemberFilter(Predicate lambdaMemberFilter) { + lambdaMemberFilters.add(lambdaMemberFilter); + } + private static Class resolveRawClass(Type genericType, Class subType, Class functionalInterface) { if (genericType instanceof Class) { return (Class) genericType; @@ -700,10 +709,11 @@ private static Member getMemberRef(Class type) { if (member == null || (member instanceof Constructor && member.getDeclaringClass().getName().equals("java.lang.invoke.SerializedLambda")) - // Skip member generated by jrebel - || member.getDeclaringClass().getName().startsWith("com.zeroturnaround.jrebelbase.facade.") || member.getDeclaringClass().isAssignableFrom(type)) continue; + if (testAllLambdaMemberFilters(member)) { + continue; + } result = member; @@ -715,6 +725,18 @@ private static Member getMemberRef(Class type) { return result; } + /** + * test member by custom lambda member filters, using AND operator. + */ + private static boolean testAllLambdaMemberFilters(Member member) { + for (Predicate lambdaMemberFilter : lambdaMemberFilters) { + if (lambdaMemberFilter.test(member)) { + return true; + } + } + return false; + } + private static boolean isAutoBoxingMethod(Method method) { Class[] parameters = method.getParameterTypes(); return method.getName().equals("valueOf") && parameters.length == 1 && parameters[0].isPrimitive()