1

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

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

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

但我正在努力告诉 JavaPoetMyClass应该实现MyInterface. 该方法addSuperinterface(TypeName)需要一个类型名称,但我没有找到如何将 aTypeSpec变成TypeName. 我发现的唯一方法是调用ClassName#get(String, String).

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

4

1 回答 1

1

它并不像看起来那么复杂。TypeSpec.Builder 有两个版本的 addSuperInterface 方法:

TypeSpec.Builder    addSuperinterface(Type superinterface) 
TypeSpec.Builder    addSuperinterface(TypeName superinterface)

例如,我们可以使用第二个版本,并使用以下方法获取超级接口作为 TypeName 类的实例ClassName.get

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

public static ClassName get(String packageName, String simpleName, String... simpleNames)

所以我们可以使用空字符串作为包名,因为您没有在接口规范中指定任何包名。它将起作用,因为 ClassName扩展了 TypeName。另一方面,我们可以使用类型规范的 name 属性获取接口的简单名称。

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

@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();
    }
}

我将 Lombok 的@Data用于样板代码(getter 和 setter ...)这是一个相应的测试(用 assertj 编写的断言):

@Test
public void should_generate_spec_with_superInterface() {
   SimpleClassSpecs ps = new SimpleClassSpecs();
   assertThat(ps.classSpec.toString()).contains("class MyClass implements MyInterface");
}

或者通过简单地做 a System.out.println(ps.classSpec),可以获得以下结果:

类 MyClass 实现 MyInterface {
}

于 2020-03-13T18:50:21.253 回答