gpt4 book ai didi

Javassist:创建一个使用泛型扩展另一个接口(interface)的接口(interface)

转载 作者:行者123 更新时间:2023-12-02 20:13:55 24 4
gpt4 key购买 nike

我正在使用javassist在一个项目中,我需要在运行时创建以下接口(interface):

package com.example;

import org.springframework.data.repository.CrudRepository;
import com.example.Cat;

public interface CatRepository extends CrudRepository<Cat, Long> {}

虽然我在创建扩展 CrudRepository 的接口(interface) CatRepository 方面没有问题,但我不明白(从文档和查看源代码),如何指定 com.example.Catjava.lang.Long 作为 super 接口(interface)的泛型类型。

请注意:

  • com.example.Cat:使用 javassist 在运行时创建(没有问题,我也测试过并且它有效
  • org.springframework.data.repository.CrudRepository:库中的现有类。

如果有人可以提供帮助,那就太好了!

谢谢!卢卡

最佳答案

简短回答

可以使用 SignatureAttribute 在 Javassist 中操作通用信息。 .

长答案(带代码)

您可能已经拥有的代码是这样的:

 ClassPool defaultClassPool = ClassPool.getDefault();
CtClass superInterface = defaultClassPool.getCtClass(CrudRepository.class
.getName());
CtClass catRepositoryInterface = defaultClassPool.makeInterface("CatRepository", ctClass);

// something is missing here :-(

catRepositoryInterface.toClass()

但是,就像您已经说过的那样,这不会添加有关泛型的信息。为了获得与编译源代码相同的字节码,您需要在注释所在的位置执行以下操作:

SignatureAttribute signatureAttribute = new SignatureAttribute(
classFile.getConstPool(),
"Ljava/lang/Object;Lorg/springframework/data/repository/CrudRepository<Lorg/example/Cat;Ljava/lang/Long;>;");
ClassFile metaInformation = catRepositoryInterface.getClassFile();
classFile.addAttribute(signatureAttribute);

让我们分解签名字符串以了解其中发生的情况:

  • 你看到几个L[TYPE],它是什么? L 是字节码中定义对象类的标准符号,如果您对 JVM Specification regarding descriptors 感兴趣,可以阅读更多相关内容。

  • ';'被用作多个定义之间的分隔符。让我们逐一查看:

    • Ljava/lang/对象
    • Lorg/springframework/data/repository/CrudRepository <Lorg/example/Cat;Ljava/lang/Long;>

第一个定义必须在那里,因为在 Java 语言中,一切都从 java.lang.Object 扩展(无论是类还是接口(interface))。

但最有趣的是第二个,您的类型具有完整的类名和泛型类型定义,所有内容都使用 L 表示法。这就是你所缺少的:-)

<小时/>

注意

请记住,如果您想从多个接口(interface)扩展,您只需将它们添加到列表中,例如,以下签名将使接口(interface)不仅从 CrudRepository 扩展,还从 Serialized 扩展:

Ljava/lang/object;Lorg/springframework/data/repository/CrudRepository<Lorg/example/Cat;Ljava/lang/Long;>;**Ljava/io/Serializable;**

关于Javassist:创建一个使用泛型扩展另一个接口(interface)的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31050473/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com