From 74db3733a229cc9e75f4c769e66cc3a8b44d5b4a Mon Sep 17 00:00:00 2001 From: wy Date: Sun, 11 Dec 2022 10:46:29 +0800 Subject: [PATCH] =?UTF-8?q?perf(core):=20=E6=94=B9=E7=94=A8=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E5=AE=89=E5=85=A8=E7=9A=84=E6=96=B9=E5=BC=8F=E4=BB=8E?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E4=B8=AD=E8=8E=B7=E5=8F=96lambda=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/lang/func/LambdaFactory.java | 89 +++++++++---------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaFactory.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaFactory.java index f8c58d79f..99e9e00bd 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaFactory.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaFactory.java @@ -66,52 +66,49 @@ public class LambdaFactory { Assert.notNull(functionInterfaceType); Assert.notNull(method); Tuple cacheKey = new Tuple(functionInterfaceType, method); - Object cacheValue = CACHE.get(cacheKey); - if (null != cacheValue) { - //noinspection unchecked - return (F) cacheValue; - } - List abstractMethods = Arrays.stream(functionInterfaceType.getMethods()) - .filter(m -> Modifier.isAbstract(m.getModifiers())) - .collect(Collectors.toList()); - Assert.equals(abstractMethods.size(), 1, "不支持非函数式接口"); - if (!method.isAccessible()) { - method.setAccessible(true); - } - Method invokeMethod = abstractMethods.get(0); - MethodHandles.Lookup caller = LookupFactory.lookup(method.getDeclaringClass()); - String invokeName = invokeMethod.getName(); - MethodType invokedType = methodType(functionInterfaceType); - MethodType samMethodType = methodType(invokeMethod.getReturnType(), invokeMethod.getParameterTypes()); - MethodHandle implMethod = Opt.ofTry(() -> caller.unreflect(method)).get(); - MethodType insMethodType = methodType(method.getReturnType(), method.getDeclaringClass(), method.getParameterTypes()); - boolean isSerializable = Arrays.stream(functionInterfaceType.getInterfaces()).anyMatch(i -> i.isAssignableFrom(Serializable.class)); - CallSite callSite = Opt.ofTry(() -> isSerializable ? - LambdaMetafactory.altMetafactory( - caller, - invokeName, - invokedType, - samMethodType, - implMethod, - insMethodType, - FLAG_SERIALIZABLE - ) : - LambdaMetafactory.metafactory( - caller, - invokeName, - invokedType, - samMethodType, - implMethod, - insMethodType - )).get(); + //noinspection unchecked + return (F) CACHE.computeIfAbsent(cacheKey, key -> { + List abstractMethods = Arrays.stream(functionInterfaceType.getMethods()) + .filter(m -> Modifier.isAbstract(m.getModifiers())) + .collect(Collectors.toList()); + Assert.equals(abstractMethods.size(), 1, "不支持非函数式接口"); + if (!method.isAccessible()) { + method.setAccessible(true); + } + Method invokeMethod = abstractMethods.get(0); + MethodHandles.Lookup caller = LookupFactory.lookup(method.getDeclaringClass()); + String invokeName = invokeMethod.getName(); + MethodType invokedType = methodType(functionInterfaceType); + MethodType samMethodType = methodType(invokeMethod.getReturnType(), invokeMethod.getParameterTypes()); + MethodHandle implMethod = Opt.ofTry(() -> caller.unreflect(method)).get(); + MethodType insMethodType = methodType(method.getReturnType(), method.getDeclaringClass(), method.getParameterTypes()); + boolean isSerializable = Arrays.stream(functionInterfaceType.getInterfaces()).anyMatch(i -> i.isAssignableFrom(Serializable.class)); + CallSite callSite = Opt.ofTry(() -> isSerializable ? + LambdaMetafactory.altMetafactory( + caller, + invokeName, + invokedType, + samMethodType, + implMethod, + insMethodType, + FLAG_SERIALIZABLE + ) : + LambdaMetafactory.metafactory( + caller, + invokeName, + invokedType, + samMethodType, + implMethod, + insMethodType + )).get(); + + try { + //noinspection unchecked + return (F) callSite.getTarget().invoke(); + } catch (Throwable e) { + throw new RuntimeException(e); + } + }); - try { - //noinspection unchecked - F lambda = (F) callSite.getTarget().invoke(); - CACHE.put(cacheKey, lambda); - return lambda; - } catch (Throwable e) { - throw new RuntimeException(e); - } } }