You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建Gradle任务修改Java源码类型并注释指定方法调用

如何创建Gradle任务实现Java源码复制与特定类替换、注释处理

我来帮你实现这个Gradle任务,核心思路是先把源码复制到临时目录,再用JavaParser(比正则更靠谱的Java代码解析工具)来处理代码修改,避免正则处理Java语法带来的各种坑。

1. 先在Gradle里引入JavaParser依赖

因为要解析和修改Java代码,我们需要JavaParser库,在你的build.gradle(Groovy)或者build.gradle.kts(Kotlin)里添加依赖:

Groovy 版本

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.github.javaparser:javaparser-core:3.25.8'
    }
}

Kotlin 版本

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("com.github.javaparser:javaparser-core:3.25.8")
    }
}

2. 编写Gradle任务

这个任务分为两个阶段:复制源码到临时目录,遍历临时目录的Java文件并修改代码。

Groovy 版本的任务代码

task processSourceCode(type: Copy) {
    // 第一阶段:复制源码到临时目录,比如 build/tmp/processedSources
    from 'src/main/java'
    into 'build/tmp/processedSources'

    // 复制完成后执行代码修改逻辑
    doLast {
        def targetDir = file('build/tmp/processedSources')
        // 遍历所有Java文件
        targetDir.eachFileRecurse(groovy.io.FileType.FILES) { file ->
            if (file.name.endsWith('.java')) {
                processJavaFile(file)
            }
        }
    }
}

// 核心方法:处理单个Java文件
void processJavaFile(File file) {
    // 解析Java文件
    def cu = com.github.javaparser.JavaParser.parse(file)

    // 1. 替换所有com.a.*类型的字段、方法参数、返回值为java.lang.Object
    cu.findAll(com.github.javaparser.ast.body.VariableDeclarator.class).each { var ->
        def type = var.getType()
        if (type.isReferenceType() && type.asReferenceType().getQualifiedName().startsWith('com.a.')) {
            var.setType(com.github.javaparser.ast.type.Type.objectType())
        }
    }

    cu.findAll(com.github.javaparser.ast.body.Parameter.class).each { param ->
        def type = param.getType()
        if (type.isReferenceType() && type.asReferenceType().getQualifiedName().startsWith('com.a.')) {
            param.setType(com.github.javaparser.ast.type.Type.objectType())
        }
    }

    cu.findAll(com.github.javaparser.ast.body.MethodDeclaration.class).each { method ->
        def returnType = method.getType()
        if (returnType.isReferenceType() && returnType.asReferenceType().getQualifiedName().startsWith('com.a.')) {
            method.setType(com.github.javaparser.ast.type.Type.objectType())
        }

        // 2. 注释所有调用java.lang.Object方法的代码行
        method.findAll(com.github.javaparser.ast.expr.MethodCallExpr.class).each { call ->
            def scope = call.getScope().orElse(null)
            if (scope != null && (scope.toString().startsWith('java.lang.Object') || scope.toString() == 'Object')) {
                // 获取当前调用所在的语句
                def stmt = call.findAncestor(com.github.javaparser.ast.stmt.Statement.class).orElse(null)
                if (stmt != null) {
                    // 添加单行注释
                    stmt.setLineComment("// 注释Object方法调用: " + stmt.toString().trim())
                }
            }
        }
    }

    // 处理强制类型转换:把(com.a.*)的转换换成(Object)
    cu.findAll(com.github.javaparser.ast.expr.CastExpr.class).each { cast ->
        def type = cast.getType()
        if (type.isReferenceType() && type.asReferenceType().getQualifiedName().startsWith('com.a.')) {
            cast.setType(com.github.javaparser.ast.type.Type.objectType())
        }
    }

    // 把修改后的代码写回文件
    file.text = cu.toString()
}

代码逻辑说明

  • 复制阶段:用Gradle内置的Copy任务把源码复制到临时目录,避免直接修改原源码。
  • 类型替换:遍历所有字段、方法参数、返回值,只要类型是com.a.*开头的引用类型,就替换为java.lang.Object。
  • 注释Object方法调用:找到所有调用Object类方法的语句,给这些语句添加单行注释。
  • 强制类型转换处理:把原有的(com.a.ClassX)强制转换替换为(Object),和示例保持一致。

3. 运行任务

在终端执行:

./gradlew processSourceCode

执行完成后,你可以在build/tmp/processedSources目录下找到修改后的源码。

针对你提供的示例代码的处理结果

原代码修改后会变成(包含注释Object方法调用的部分):

public final class MyClass {
 private java.lang.Object varA_A;
 private java.lang.Object varA_B;
 private com.b.ClassA varB_A;
 public Something(java.lang.Object paramA_A, com.b.ClassA paramB_A, java.lang.Object paramA_B) {
 //construct
 }
 public static final java.lang.Object getInstance(java.lang.Object paramA_C, com.b.ClassA paramB_A) {
 Object temp = null;
 if (1 == 1) {
 // 注释Object方法调用: temp = java.lang.Object.method(paramA_C);
 temp = java.lang.Object.method(paramA_C);
 } else {
 temp = com.b.ClassB.method(paramA_C);
 }
 return (java.lang.Object) temp;
 }
}

注意事项

  • 如果你用的是Kotlin DSL,只需要把Groovy代码转换成对应的Kotlin语法即可,核心逻辑完全一致。
  • JavaParser版本可以根据需要升级,最新版本可以在Maven Central上查看。
  • 建议先在测试目录运行任务,确认修改结果符合预期后再处理正式源码。

内容的提问来源于stack exchange,提问作者YounesMMM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 12:53:12