首页 > 编程语言 >java 根据 lambda 解析出原数据

java 根据 lambda 解析出原数据

时间:2022-10-12 13:34:17浏览次数:55  
标签:return String SerializedLambda private 出原 java public lambda

    /**
     * 解析 lambda 表达式, 该方法只是调用了 {@link SerializedLambda#resolve(SFunction)} 中的方法,在此基础上加了缓存。
     * 该缓存可能会在任意不定的时间被清除
     *
     * @param func 需要解析的 lambda 对象
     * @param <T>  类型,被调用的 Function 对象的目标类型
     * @return 返回解析后的结果
     * @see SerializedLambda#resolve(SFunction)
     */
    public static <T> SerializedLambda resolve(SFunction<T, ?> func) {
        Class<?> clazz = func.getClass();
        String name = clazz.getName();
        return Optional.ofNullable(FUNC_CACHE.get(name))
                .map(WeakReference::get)
                .orElseGet(() -> {
                    SerializedLambda lambda = SerializedLambda.resolve(func);
                    FUNC_CACHE.put(name, new WeakReference<>(lambda));
                    return lambda;
                });
    }

上面的代码为 com.baomidou.mybatisplus.core.toolkit.LambdaUtils

 

参考: https://gist.github.com/jhorstmann/de367a42a08d8deb8df9

类: com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda

类: java.lang.invoke.SerializedLambda

 

/*
 * Copyright (c) 2011-2020, baomidou ([email protected]).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.baomidou.mybatisplus.core.toolkit.support;

import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.baomidou.mybatisplus.core.toolkit.SerializationUtils;

import java.io.*;

/**
 * 这个类是从 {@link java.lang.invoke.SerializedLambda} 里面 copy 过来的,
 * 字段信息完全一样
 * <p>负责将一个支持序列的 Function 序列化为 SerializedLambda</p>
 *
 * @author HCL
 * @since 2018/05/10
 */
@SuppressWarnings("unused")
public class SerializedLambda implements Serializable {

    private static final long serialVersionUID = 8025925345765570181L;

    private Class<?> capturingClass;
    private String functionalInterfaceClass;
    private String functionalInterfaceMethodName;
    private String functionalInterfaceMethodSignature;
    private String implClass;
    private String implMethodName;
    private String implMethodSignature;
    private int implMethodKind;
    private String instantiatedMethodType;
    private Object[] capturedArgs;

    /**
     * 通过反序列化转换 lambda 表达式,该方法只能序列化 lambda 表达式,不能序列化接口实现或者正常非 lambda 写法的对象
     *
     * @param lambda lambda对象
     * @return 返回解析后的 SerializedLambda
     */
    public static SerializedLambda resolve(SFunction<?, ?> lambda) {
        if (!lambda.getClass().isSynthetic()) {
            throw ExceptionUtils.mpe("该方法仅能传入 lambda 表达式产生的合成类");
        }
        try (ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(SerializationUtils.serialize(lambda))) {
            @Override
            protected Class<?> resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException {
                Class<?> clazz;
                try {
                    clazz = ClassUtils.toClassConfident(objectStreamClass.getName());
                } catch (Exception ex) {
                    clazz = super.resolveClass(objectStreamClass);
                }
                return clazz == java.lang.invoke.SerializedLambda.class ? SerializedLambda.class : clazz;
            }
        }) {
            return (SerializedLambda) objIn.readObject();
        } catch (ClassNotFoundException | IOException e) {
            throw ExceptionUtils.mpe("This is impossible to happen", e);
        }
    }

    /**
     * 获取接口 class
     *
     * @return 返回 class 名称
     */
    public String getFunctionalInterfaceClassName() {
        return normalizedName(functionalInterfaceClass);
    }

    /**
     * 获取实现的 class
     *
     * @return 实现类
     */
    public Class<?> getImplClass() {
        return ClassUtils.toClassConfident(getImplClassName());
    }

    /**
     * 获取 class 的名称
     *
     * @return 类名
     */
    public String getImplClassName() {
        return normalizedName(implClass);
    }

    /**
     * 获取实现者的方法名称
     *
     * @return 方法名称
     */
    public String getImplMethodName() {
        return implMethodName;
    }

    /**
     * 正常化类名称,将类名称中的 / 替换为 .
     *
     * @param name 名称
     * @return 正常的类名
     */
    private String normalizedName(String name) {
        return name.replace('/', '.');
    }

    /**
     * @return 获取实例化方法的类型
     */
    public Class<?> getInstantiatedType() {
        String instantiatedTypeName = normalizedName(instantiatedMethodType.substring(2, instantiatedMethodType.indexOf(';')));
        return ClassUtils.toClassConfident(instantiatedTypeName);
    }

    /**
     * @return 字符串形式
     */
    @Override
    public String toString() {
        String interfaceName = getFunctionalInterfaceClassName();
        String implName = getImplClassName();
        return String.format("%s -> %s::%s",
                interfaceName.substring(interfaceName.lastIndexOf('.') + 1),
                implName.substring(implName.lastIndexOf('.') + 1),
                implMethodName);
    }

}

 

标签:return,String,SerializedLambda,private,出原,java,public,lambda
From: https://www.cnblogs.com/whm-blog/p/16784220.html

相关文章

  • java--面向对象
    面向==对象==OO:OritenedObjectOOP:使用oo的思想进行开发。利用对象实现功能。  面向对象编程。1.封装2.继承3.多态   面向过程c vs 面向对象......
  • Java Heap
    堆堆是一种基于树的数据结构,是一种完全二叉树,堆中的所有的节点都按照特定的顺序排列。在堆数据结构中,如果任意父节点的值都大于其子节点,则会产生一个大顶堆;反之,如果任......
  • python lambda匿名函数
    例如:lambdax,y:x*x+y*y如何调用lambda函数?1、赋值f=lambdastr:len(str.split())f('helloworld')2、(lambdastr:len(str.split()))('helloworld')......
  • Java代码如何编写世界上最漂亮的null判断代码呢?
    转自:​​http://www.java265.com/JavaJingYan/202205/16524508473361.html​​null:  空对象,通常指一个引用对象没有在堆上产生,没有指向任何东西,  此时它就是一个nu......
  • java函数式编程
    importcom.alibaba.fastjson.JSON;importcom.ctrip.car.osd.util.LogHelper;importorg.apache.commons.collections.CollectionUtils;importjava.util.ArrayList;......
  • 关于lambda的由来
    总结lambda表达式的本质就是匿名方法,根据委托推断类型classProgram{staticvoidMain(string[]args){//泛型委托最后一个是返......
  • JAVA反射Runtime类研究
    Runtime类在java中一般类的调用方法是new类();所以我们使用newRuntime()来实例化一个Runtime类的对象importjava.io.IOException;publicclassmain{public......
  • 关于Java中length、length()、size()的区别
    以前总是觉得自己好像会了,但是某天忽然面对这个笔试题还是会恍惚一下,混淆和答错的几率也很大,不知道有没有其他人像我一样的。所以今天把这个问题记一下,希望印象更深刻。......
  • WebAssembly01--在JavaScript中读写C/C++内存
    编译选项emccmem.cc-omem.jsmem.cc#include"util.h"intg_int=42;doubleg_double=3.1415926;EM_PORT_API(int*)get_int_ptr(){return&g_int;}EM_PO......
  • java 实现接口频次限制
    1、添加依赖<dependency><groupId>net.jodah</groupId><artifactId>expiringmap</artifactId><version>0.5.10</versio......