考虑这个例子,我正在寻找这种问题的一般解决方案。
我正在开发一个为类创建接口的注释处理器,基本上复制了所有公共方法。可以使用String参数配置接口的名称(和包)。但由于注释为@Inherited
,因此应该能够定义将子类名称映射到其接口名称的InterfaceNamingStrategy
。
我尝试在this answer之后使用动态注释参数。
/**
* Generates an interface that contains all public member mehtods of the annotated class.
* This can only be used on top-level classes.
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
@Inherited
@Documented
public @interface GenerateInterface {
/**
* Name of the generated interface. If this is not specified, the {@link #namingStrategy()}
* is used to retrieve the interface name.
* If the name is not fully qualified, the interface will have the same package
* as the annotated class.
*/
String value() default "";
/**
* An implementation of {@link InterfaceNamingStrategy} that returns the interface name
* for a given annotated class. It must be accessible and contain a public no-arg constructor.
*/
Class<? extends InterfaceNamingStrategy> namingStrategy() default InterfaceNamingStrategy.PrefixI.class;
}
/**
* Naming strategy to be used with {@link GenerateInterface}.
*/
public interface InterfaceNamingStrategy {
/**
* @param impl TypeElement representing the annotated class
* @return the name of the generated interface. See {@link GenerateInterface#value()}.
*/
String getInterfaceName(TypeElement impl);
/**
* Will create the interface {@code Foo} for the annotated class {@code FooImpl}
*/
public static class ExceptLastFourChars implements InterfaceNamingStrategy {
@Override
public String getInterfaceName(TypeElement impl) {
return impl.getSimpleName().toString().substring(0, impl.getSimpleName().length()-4);
}
}
/**
* Will create the interface {@code IFoo} for the annotated class {@code Foo}
*/
public static class PrefixI implements InterfaceNamingStrategy {
@Override
public String getInterfaceName(TypeElement impl) {
return "I" + impl.getSimpleName();
}
}
}
但是,这在编译时处理注释时不起作用,因为您无法实例化InterfaceNamingStrategy
中所述function isString(value: any): value is string {
return typeof value === 'string' || value instanceof String;
}
function foo(param: string | Foo) {
if (isString(param)) {
// param is string
} else {
// param is Foo
}
}
的实现。
有没有办法将动态参数传递给在编译时处理的注释?
我目前的解决方案是使用String参数和this question。但我更喜欢使用实际经过类型检查的Java代码的解决方案。