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

com.jl.JLambda Maven / Gradle / Ivy

The newest version!
package com.jl;

import lombok.SneakyThrows;
import org.springframework.util.ClassUtils;

import java.beans.Introspector;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.util.function.Function;

/**
 * lambda解析工具
 */
public class JLambda {

    /**
     * 获取属性名
     *
     * @param function
     * @param 
     * @return
     */
    public static  String getProperty(JFunction function) {
        return findField(function, "property").getV3();
    }

    /**
     * 获取方法名
     *
     * @param function
     * @param 
     * @return
     */
    public static  String getMethod(JFunction function) {
        return findField(function, "method").getV2();
    }

    /**
     * 获取类class
     *
     * @param function
     * @param 
     * @return
     */
    public static  Class getClass(JFunction function) {
        return findField(function, "class").getV1();
    }

    @SneakyThrows
    private static  JTuple.Tuple3, String, String> findField(JFunction function, String way) {
        String propertyName = null;
        // 第1步 获取SerializedLambda
        Method method = function.getClass().getDeclaredMethod("writeReplace");
        method.setAccessible(Boolean.TRUE);
        SerializedLambda serializedLambda = (SerializedLambda) method.invoke(function);
        // 第2步 implMethodName 即为Field对应的Getter方法名
        String implMethodName = serializedLambda.getImplMethodName();
        if (implMethodName.startsWith("lambda$")) {
            throw new IllegalArgumentException("不能传递lambda表达式,只能使用方法引用");
        }
        if (way.equals("property")) {
            if (implMethodName.startsWith("get") && implMethodName.length() > 3) {
                propertyName = Introspector.decapitalize(implMethodName.substring(3));
            } else {
                throw new IllegalArgumentException(implMethodName + "不是Getter方法引用");
            }
        }
        // 第3步 获取的Class是字符串,并且包名是“/”分割,需要替换成“.”,才能获取到对应的Class对象
        String declaredClass = serializedLambda.getImplClass().replace("/", ".");
        Class classz = (Class) Class.forName(declaredClass, false, ClassUtils.getDefaultClassLoader());
        // 第4步  Spring 中的反射工具类获取Class中定义的Field(此步为扩展,可省略)
            /*Field field = ReflectionUtils.findField(classz, propertyName);
            if (field == null) {
                return null;
            }
            classz = field.getDeclaringClass();*/
        //封装类class、方法名、属性名
        JTuple.Tuple3, String, String> tuple3 = new JTuple.Tuple3<>(classz, implMethodName, propertyName);
        return tuple3;
    }

    /**
     * 函数式接口
     *
     * @param  引用实体类型
     * @param  引用方法返回值类型
     */
    @FunctionalInterface
    public interface JFunction extends Function, Serializable {

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy