【问题标题】:IntelliJ IDEA @ParametersAreNonnullByDefault for all subpackagesIntelliJ IDEA @ParametersAreNonnullByDefault 适用于所有子包
【发布时间】:2017-02-26 07:24:03
【问题描述】:

我使用 IntelliJ 的 null-checking 机制来防止 nullpointer 崩溃。 我已经成功地使用this答案将所有Java方法参数默认设置为@NonNull。

在创建 package-info.java 之后,它用于在 Java 中定义 package annotations。在我的 Android Studio 项目中,作为该包的直接后代的所有 java 文件都有带有默认 @NonNull 参数的方法。

明显的问题是我需要为该包中的所有 Java 类定义 @ParametersAreNonnullByDefault,即包括所有子包

如何定义 @ParametersAreNonnullByDefault 以便它向下传播到所有子包 java 文件?我希望我的所有内部代码的方法默认都用 @NonNull 注释。

/**
  * File: package-info.java
  * Make all method parameters @NonNull by default
  */
  @ParametersAreNonnullByDefault
  package com.intive.nearbyplaces.main;

  import javax.annotation.ParametersAreNonnullByDefault;

【问题讨论】:

    标签: java android-studio intellij-idea nullable non-nullable


    【解决方案1】:

    问题是我不能强制 Android Studio 在所有子包中尊重 @ParametersAreNonnullByDefault(即递归地用于 com.company.name 中的所有 java 文件)

    我写了一个 gradle 脚本,但是,来检查每个子包文件夹中是否生成了 package-info.java 文件,并在必要时创建它。该脚本在 assembleDebug 任务之前运行。

    事实证明,可以在项目中的所有 java 类上强制 @ParametersAreNonnullByDefault 注释。

    下载源代码here。请记住将第 19 行替换为您的包名

    用法:

    apply plugin: 'com.android.application'
    apply from: 'nonnull.gradle'
    
    android {
       compileSdkVersion 24
       buildToolsVersion "24.0.2"
    
       [...]
    }
    

    记得在 .gitignore

    中包含 package-info.java 文件
    //File: .gitignore 
    
    package-info.java
    

    Checkstyle 规则:

    <module name="JavadocPackage"/>
    

    检查 package-info.java 是否包含在每个子包中。

    来源:

    /**
     *  File: nonnull.gradle
     *
     *  Generates package-info.java for appropriate packages
     *  inside src/main/java folder.
     *
     *  This is a workaround to define @ParametersAreNonnullByDefault for all Java classes in a package
     *  i.e. including all subpackages (note: edit package name in line no. 19).
     */
    task generateNonNullJavaFiles(dependsOn: "assembleDebug", type: Copy) {
        group = "Copying"
        description = "Generate package-info.java classes"
    
        def infoFileContentHeader = getFileContentHeader();
        def infoFileContentFooter = getFileContentFooter();
    
        def sourceDir = file( "${projectDir}" + File.separatorChar + "src" + File.separatorChar +
                "main" + File.separatorChar + "java" + File.separatorChar +
                "com" + File.separatorChar + "company" + File.separatorChar + "name" )
        sourceDir.eachDirRecurse { dir ->
            def infoFilePath = dir.getAbsolutePath() + File.separatorChar + "package-info.java"
    
            if (!file(infoFilePath).exists()) {
                def infoFileContentPackage = getFileContentPackage(dir.getAbsolutePath());
                new File(infoFilePath).write(infoFileContentHeader +
                        infoFileContentPackage + infoFileContentFooter)
                println "[dir] " + infoFilePath + "  created";
            }
        }
        println "[SUCCESS] NonNull generator: package-info.java files checked"
    }
    
    def getFileContentPackage(path) {
        def mainSrcPhrase = "src" + File.separatorChar + "main" + File.separatorChar +
                "java" + File.separatorChar
        def mainSrcPhraseIndex = path.indexOf(mainSrcPhrase)
        def output = path.substring(mainSrcPhraseIndex)
    
        // Win hotfix
        if (System.properties['os.name'].toLowerCase().contains('windows')) {
            output = output.replace("\\", "/")
            mainSrcPhrase = mainSrcPhrase.replace("\\", "/")
        }
    
        return "package " + output.replaceAll(mainSrcPhrase, "").replaceAll(
                "/", ".") + ";\n"
    }
    
    def getFileContentHeader() {
        return  "/** javadoc goes here \n */\n" +
                "@ParametersAreNonnullByDefault\n" +
                "@ReturnValuesAreNonnullByDefault\n"
    }
    
    def getFileContentFooter() {
        return  "\n" +
                "import javax.annotation.ParametersAreNonnullByDefault;\n" +
                "\n" +
                "import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;"
    }
    

    为 src main、test 和 androidTest 文件夹生成包信息文件的扩展版本可以在 here 找到。

    查找错误和皮棉:

    确实可以使用 findbugs & lint。

    【讨论】:

    • 这很简洁,但不能用于 Maven :(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    • 2020-04-23
    相关资源
    最近更新 更多