This commit is contained in:
Looly 2022-03-25 02:05:58 +08:00
parent e76d2e13cb
commit 59f7708924
5 changed files with 67 additions and 7 deletions

View File

@ -1,10 +1,11 @@
package cn.hutool.core.lang.func;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.SimpleCache;
import cn.hutool.core.text.CharPool;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
@ -85,7 +86,7 @@ public class LambdaUtil {
* @since 5.8.0
*/
public static <R> Class<R> getImplClass(Func0<?> func) {
return ClassUtil.loadClass(resolve(func).getImplClass().replace(CharPool.SLASH, CharPool.DOT));
return ClassUtil.loadClass(resolve(func).getImplClass());
}
/**
@ -103,7 +104,36 @@ public class LambdaUtil {
* @since 5.8.0
*/
public static <T> Class<T> getImplClass(Func1<T, ?> func) {
return ClassUtil.loadClass(resolve(func).getImplClass().replace(CharPool.SLASH, CharPool.DOT));
return ClassUtil.loadClass(resolve(func).getImplClass());
}
/**
* 通过{@link SerializedLambda#getInstantiatedMethodType()}获取lambda实现类<br>
* 在使用{@link #getImplClass(Func0)}获取实现类的时候如果传入的是父类方法引用会返回父类导致问题<br>
* 此类通过方法的名称截取出类名
*
* @param func lambda
* @param <P> 类型
* @return lambda实现类
*/
public static <P> Class<P> getInstantiatedClass(Func0<?> func) {
final String instantiatedMethodType = resolve(func).getInstantiatedMethodType();
Console.log(instantiatedMethodType);
return ClassUtil.loadClass(StrUtil.sub(instantiatedMethodType, 2, StrUtil.indexOf(instantiatedMethodType, ';')));
}
/**
* 通过{@link SerializedLambda#getInstantiatedMethodType()}获取lambda实现类<br>
* 在使用{@link #getImplClass(Func1)}获取实现类的时候如果传入的是父类方法引用会返回父类导致问题<br>
* 此类通过方法的名称截取出类名
*
* @param func lambda
* @param <P> 类型
* @return lambda实现类
*/
public static <P> Class<P> getInstantiatedClass(Func1<P, ?> func) {
final String instantiatedMethodType = resolve(func).getInstantiatedMethodType();
return ClassUtil.loadClass(StrUtil.sub(instantiatedMethodType, 2, StrUtil.indexOf(instantiatedMethodType, ';')));
}
/**

View File

@ -5,6 +5,7 @@ import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.JarClassLoader;
import cn.hutool.core.lang.SimpleCache;
import cn.hutool.core.text.CharPool;
import java.io.File;
import java.lang.reflect.Array;
@ -186,6 +187,9 @@ public class ClassLoaderUtil {
public static Class<?> loadClass(String name, ClassLoader classLoader, boolean isInitialized) throws UtilException {
Assert.notNull(name, "Name must not be null");
// 自动将包名中的"/"替换为"."
name = name.replace(CharPool.SLASH, CharPool.DOT);
// 加载原始类型和缓存中的类
Class<?> clazz = loadPrimitiveClass(name);
if (clazz == null) {

View File

@ -6,7 +6,11 @@ import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.map.MapUtil;
import java.lang.reflect.Field;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
/**
@ -234,9 +238,19 @@ public class EnumUtil {
* @param <F> 想要获取的字段类型
* @param <C> 条件字段类型
* @return 对应枚举中另一字段值 获取不到时为 {@code null}
* @since 5.8.0
*/
public static <E extends Enum<E>, F, C> F getFieldBy(Function<E, F> field, Func1<E, C> condition, C value) {
return Arrays.stream(LambdaUtil.getImplClass(condition).getEnumConstants()).filter(e -> condition.callWithRuntimeException(e).equals(value)).findAny().map(field).orElse(null);
public static <E extends Enum<E>, F, C> F getFieldBy(Func1<E, F> field,
Function<E, C> condition, C value) {
Class<E> implClass = LambdaUtil.getImplClass(field);
if(Enum.class.equals(implClass)){
implClass = LambdaUtil.getInstantiatedClass(field);
}
return Arrays.stream(implClass.getEnumConstants())
// 过滤
.filter(e -> condition.apply(e).equals(value))
// 获取第一个并转换为结果
.findFirst().map(field::callWithRuntimeException).orElse(null);
}
/**

View File

@ -36,6 +36,14 @@ public class LambdaUtilTest {
Assert.assertEquals(MyTeacher.class, aClass);
}
@Test
public void getInstantiatedClassTest() {
// 类方法引用相当于获取的方法引用是MyTeacher.getAge(this)
// 因此此处会匹配到Func1其参数就是this
Class<MyTeacher> aClass = LambdaUtil.getInstantiatedClass(MyTeacher::getAge);
Assert.assertEquals(MyTeacher.class, aClass);
}
@Data
static class MyTeacher {

View File

@ -44,8 +44,11 @@ public class EnumUtilTest {
@Test
public void getFieldByTest() {
// 枚举中字段互相映射使用
String type = EnumUtil.getFieldBy(TestEnum::getType, TestEnum::ordinal, 1);
String type = EnumUtil.getFieldBy(TestEnum::getType, Enum::ordinal, 1);
Assert.assertEquals("type2", type);
int ordinal = EnumUtil.getFieldBy(TestEnum::ordinal, Enum::ordinal, 1);
Assert.assertEquals(1, ordinal);
}
@Test
@ -75,6 +78,7 @@ public class EnumUtilTest {
}
private final String type;
@SuppressWarnings("unused")
private String name;
public String getType() {