Javassist:创建一个用泛型扩展另一个接口的接口
我正在项目中使用,需要在运行时创建以下接口:Javassist:创建一个用泛型扩展另一个接口的接口,java,javassist,Java,Javassist,我正在项目中使用,需要在运行时创建以下接口: package com.example; import org.springframework.data.repository.CrudRepository; import com.example.Cat; public interface CatRepository extends CrudRepository<Cat, Long> {} package.com.example; 导入org.springframework.dat
package com.example;
import org.springframework.data.repository.CrudRepository;
import com.example.Cat;
public interface CatRepository extends CrudRepository<Cat, Long> {}
package.com.example;
导入org.springframework.data.repository.crudepository;
导入com.example.Cat;
公共接口CatRepository扩展了Crudepository{}
虽然我在创建接口CatRepository
扩展crudepository
时没有遇到问题,但我不明白(从文档和查看源代码)如何将com.example.Cat
和java.lang.Long
指定为超级接口的泛型类型
请注意:
:使用javassist在运行时创建(没有问题,我也测试过,它可以正常工作)com.example.Cat
:库中存在的类org.springframework.data.repository.crudepository
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);
SignatureAttribute SignatureAttribute=新的SignatureAttribute(
classFile.getConstPool(),
“Ljava/lang/Object;Lorg/springframework/data/repository/crudepository;”;
ClassFile metaInformation=catRepositoryInterface.getClassFile();
addAttribute(signatureAttribute);
让我们对签名字符串进行分解,以了解其中发生的情况:
- 你会看到几个L[TYPE],它是什么?L是字节码中定义对象类的标准符号,如果你对
- “;”被用作多个定义之间的分隔符。让我们看看其中的每一个:
- Ljava/lang/Object
- Lorg/springframework/data/repository/Crudepository
注意 请记住,如果要从多个接口扩展,只需将它们添加到列表中即可。例如,以下签名将使接口不仅从CrudePository扩展,而且从Serializable扩展:
Ljava/lang/object;Lorg/springframework/data/repository/CrudRepository<Lorg/example/Cat;Ljava/lang/Long;>;**Ljava/io/Serializable;**
Ljava/lang/object;Lorg/springframework/data/repository/Crudepository**Ljava/io/Serializable**
回答得很好。成功了!谢谢你的完美描述!我会仔细研究,以进一步了解我在做什么。我知道这是一个古老的答案,但你能修复你的三个代码示例吗?什么是ctClass
,什么是classFile
,为什么metaInformation
从未被使用,为什么“**”有意义?