是否有用于检查字符串参数模式的android注释?

LPe*_*R90 6 java android annotations pattern-matching kotlin

问题

我正在使用Android和Kotlin,我希望有一个注释来检查常量String参数(对于函数或构造函数)是否与某个模式(正则表达式)匹配.我读到了关于模式注释的内容,但我不确定它是否适用于我的问题以及它是否适用于Android.

所以,当我有这样的代码

fun foo(@MatchesPattern("a*b") bar: String) = println(bar)
Run Code Online (Sandbox Code Playgroud)

然后

foo("aaaab")
Run Code Online (Sandbox Code Playgroud)

应该编译得很好,但是

foo("bb")
Run Code Online (Sandbox Code Playgroud)

不应该.

这可能,最好没有任何第三方库吗?如果是,我将如何实现这样的注释?(对不起,我不熟悉编写我自己的自定义注释)

背景

我希望将带有连字符分隔音节的单词作为参数传递,但是一个单词不应超过3个音节(这意味着每个单词最多2个连字符).我知道我也可以使用默认的params实现这一点,但我认为注释将是一种更优雅的方式来实现这一点.

Wil*_*ham 2

在 Android 中这并不那么简单,因为您必须创建一个新项目(java 库)来放置注释。该过程看起来像这样(未经测试)。

  1. 使用 android studio 创建一个新的 java 库作为项目中的模块(选择项目根目录,右键单击,新建模块)。这将添加一个文件夹,例如lib(如果您不更改其默认值)以及您指定的类(例如MyCustomAnnotationProcessor.

  2. 在您的应用程序目录中,转到build.gradle并修改它以包含 sourceCompatibility 和 targetCompatibility,如下所示:

    android {
        ...
        compileOptions {
            sourceCompatibility = JavaVersion.VERSION_1_8
            targetCompatibility = JavaVersion.VERSION_1_8
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 然后在lib文件中执行几乎相同的操作build.gradle(如果在步骤 2 重建后尚未存在)

    apply plugin: 'java-library'
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
    }
    
    sourceCompatibility = "1.8"
    targetCompatibility = "1.8"
    
    Run Code Online (Sandbox Code Playgroud)
  4. lib文件夹中,为注释 (an @interface) 创建一个新类,如下所示:

    @Retention(RetentionPolicy.SOURCE)
    @Target(ElementType.PARAMETER)
    public @interface PatternMatches {
        String value() default ".*";
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 修改在步骤 1 中创建的注释处理器。请注意,此 extendsjavax.annotation.processing.AbstractProcessor仅在此处可用,因为我们位于 java 库中。

    @SupportedAnnotationTypes("your.package.PatternMatches")
    @SupportedSourceVersion(SourceVersion.RELEASE_8)
    public class MyCustomAnnotationProcessor extends AbstractProcessor {
        private ProcessingEnvironment processingEnv;
        @Override
        public synchronized void init(ProcessingEnvironment env){
            processingEnv = env;
        }
        @Override
        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
            Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(PatternMatches.class);
            Set<VariableElement> params = ElementFilter.fieldsIn(elements);
            for (VariableElement param : params) {
                String val = param.getConstantValue();
                String regex = param.getAnnotation(PatternMatches.class).value();
                if (!val.matches(regex)) {
                    processingEnv.getMessager().printMessage(
    Diagnostic.Kind.ERROR, "Regex match failed", param);
                }
            }
            return false;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)