用javapoter实现生成接口

用javapoter实现生成接口,java,code-generation,javapoet,Java,Code Generation,Javapoet,我想使用生成一个接口和一个实现该接口的类 TypeSpec if = TypeSpec.interfaceBuilder("MyInterface") .build(); TypeSpec cl = TypeSpec.classBuilder("MyClass") .build(); 但我正努力告诉JavaPoet,MyClass应该实现MyInterface。方法addSuperinterface(T

我想使用生成一个接口和一个实现该接口的类

TypeSpec if = TypeSpec.interfaceBuilder("MyInterface")
                      .build();

TypeSpec cl = TypeSpec.classBuilder("MyClass")
                      .build();

但我正努力告诉JavaPoet,
MyClass
应该实现
MyInterface
。方法
addSuperinterface(TypeName)
需要一个类型名,我不知道如何将
TypeSpec
转换为
TypeName
。我找到的唯一方法是调用
ClassName#get(String,String)


有没有更好的方法来实现这一点,并直接使用接口的类型规范

事情并不像看上去那么复杂。 TypeSpec.Builder有两个版本的addSuperInterface方法:

TypeSpec.Builder    addSuperinterface(Type superinterface) 
TypeSpec.Builder    addSuperinterface(TypeName superinterface)
例如,我们可以使用第二个版本,并使用
ClassName.get

ClassName类的get方法的签名之一是:

public static ClassName get(String packageName, String simpleName, String... simpleNames)
因此,我们可以将它与空字符串一起用作包名,因为您没有在接口规范中指定任何包名。这将起作用,因为ClassName扩展了TypeName。 另一方面,我们可以使用类型规范的name属性获取接口的简单名称

这里是一个完整的示例实现。我修改了变量的名称(用于接口规范的变量名if将不起作用,因为它是一个java关键字)

我使用Lombok的@Data作为样板代码(getter和setter…) 下面是一个相应的测试(用assertj编写的断言):

或者只需执行
System.out.println(ps.classSpec)
,即可获得以下结果:

类MyClass实现MyInterface{ }

@Data
public class SimpleClassSpecs {

    public final TypeSpec interfaceSpec;
    public final TypeSpec classSpec;

    public SimpleClassSpecs() {
        interfaceSpec = TypeSpec.interfaceBuilder("MyInterface")
                .build();

        TypeName interfaceTypeName = ClassName.get("", interfaceSpec.name);
        classSpec = TypeSpec.classBuilder("MyClass")
                .addSuperinterface(interfaceTypeName)
                .build();
    }
}
@Test
public void should_generate_spec_with_superInterface() {
   SimpleClassSpecs ps = new SimpleClassSpecs();
   assertThat(ps.classSpec.toString()).contains("class MyClass implements MyInterface");
}
class MyClass implements MyInterface { }