Javassist:创建实现通用接口的 class
Javassist: Create class that implements generic interface
我正在尝试使用 javassit 创建一个 class 来实现传递通用参数的通用接口,但到目前为止没有成功。
我知道答案
and the javassit tutorial 但其中 none 有帮助。
这是我的代码:
String met = "public void doit(com.package.Pojo o) { System.out.println(\"Result: \" + o.getName()); }";
ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.makeClass("Teste");
cc.setInterfaces(new CtClass[]{cp.get("com.package.Factor")});
ClassSignature cs = new ClassSignature(null, null,
// Set interface and its generic params
new ClassType[]{new ClassType("com.package.Factor",
new TypeArgument[]{new TypeArgument(new ClassType("com.package.Pojo"))}
)});
cc.setGenericSignature(cs.encode());
//cc.setGenericSignature("Ljava/lang/Object;Lcom/aurora/core/util/Factor<Lcom/aurora/core/util/Pojo;>;");
CtMethod make = CtNewMethod.make(met, cc);
cc.addMethod(make);
Class<Factor<Pojo>> class1 = cc.toClass();
Factor<Pojo> obj = (Factor<Pojo>) class1.newInstance();
obj.doit(new Pojo("name here"));
因素class:
public interface Factor<T> {
void doit(T ent);
}
我的pom
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.20.0-GA</version>
</dependency>
错误:
Exception in thread "main" java.lang.AbstractMethodError:
Teste.doit(Ljava/lang/Object;)V
at com.package.Main3.main(Main3.java:40)
提前致谢!
Java 运行时使用类型擦除。因此,doit(T)
方法在接口类型中定义为doit(java.lang.Object)
。为了覆盖一个方法,你需要在生成的class中实现它。当你定义一个方法时,Java 编译器会透明地为你做这件事,javassist 不会为你做这件事。
因此,您需要添加一个所谓的 bridge method 调用实际方法但覆盖接口的方法:
public void doit(Object ent) {
doit((Pojo) ent);
}
我正在尝试使用 javassit 创建一个 class 来实现传递通用参数的通用接口,但到目前为止没有成功。
我知道答案
这是我的代码:
String met = "public void doit(com.package.Pojo o) { System.out.println(\"Result: \" + o.getName()); }";
ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.makeClass("Teste");
cc.setInterfaces(new CtClass[]{cp.get("com.package.Factor")});
ClassSignature cs = new ClassSignature(null, null,
// Set interface and its generic params
new ClassType[]{new ClassType("com.package.Factor",
new TypeArgument[]{new TypeArgument(new ClassType("com.package.Pojo"))}
)});
cc.setGenericSignature(cs.encode());
//cc.setGenericSignature("Ljava/lang/Object;Lcom/aurora/core/util/Factor<Lcom/aurora/core/util/Pojo;>;");
CtMethod make = CtNewMethod.make(met, cc);
cc.addMethod(make);
Class<Factor<Pojo>> class1 = cc.toClass();
Factor<Pojo> obj = (Factor<Pojo>) class1.newInstance();
obj.doit(new Pojo("name here"));
因素class:
public interface Factor<T> {
void doit(T ent);
}
我的pom
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.20.0-GA</version>
</dependency>
错误:
Exception in thread "main" java.lang.AbstractMethodError: Teste.doit(Ljava/lang/Object;)V at com.package.Main3.main(Main3.java:40)
提前致谢!
Java 运行时使用类型擦除。因此,doit(T)
方法在接口类型中定义为doit(java.lang.Object)
。为了覆盖一个方法,你需要在生成的class中实现它。当你定义一个方法时,Java 编译器会透明地为你做这件事,javassist 不会为你做这件事。
因此,您需要添加一个所谓的 bridge method 调用实际方法但覆盖接口的方法:
public void doit(Object ent) {
doit((Pojo) ent);
}