gpt4 book ai didi

java - 使用注释处理器替换代码

转载 作者:IT老高 更新时间:2023-10-28 20:53:42 24 4
gpt4 key购买 nike

我正在尝试写一个 annotation processor在类上插入方法和字段......并且文档非常稀疏。我没有走远,我不知道我是否正确地接近它。

处理环境提供Filer具有创建新源文件和类文件的便捷方法的对象。这些工作正常,但后来我试图弄清楚如何读取现有的源文件,它提供的只是“getResource”。所以在我的处理器实现中我已经这样做了:

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
try {
for (TypeElement te : annotations) {
for (Element element : roundEnv.getElementsAnnotatedWith(te)) {
FileObject in_file = processingEnv.getFiler().getResource(
StandardLocation.SOURCE_PATH, "",
element.asType().toString().replace(".", "/") + ".java");

FileObject out_file = processingEnv.getFiler().getResource(
StandardLocation.SOURCE_OUTPUT, "",
element.asType().toString().replace(".", "/") + ".java");

//if (out_file.getLastModified() >= in_file.getLastModified()) continue;

CharSequence data = in_file.getCharContent(false);

data = transform(data); // run the macro processor

JavaFileObject out_file2 = processingEnv.getFiler().createSourceFile(
element.asType().toString(), element);
Writer w = out_file2.openWriter();
w.append(data);
w.close();
}
}
} catch (Exception e) {
e.printStackTrace();
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage());
}
return true;
}

我的第一个困惑是我不禁觉得 element.asType().toString().replace(".", "/") + ".java" (获取限定类型名称并将其转换为包和源文件路径)不是解决问题的好方法。 API 的其余部分设计过度,但似乎没有一种方便的方法来检索原始源代码。

真正的问题是编译器会自发地被输出目录中的第二个源文件(“错误:重复类”)弄乱,现在我被卡住了。

我已经编写了剩下的部分——一个宏词法分析器和解析器,以及用于计算一些数据和插入字段值和方法的东西——但它作为编译器之外的初始步骤运行。除了原始文件不能具有 .java 扩展名(以防止编译器看到它们)这一事实之外,这很好用。然后听说注解可以做代码生成,我觉得会比较合适和方便,但是找不到太多的指导。

最佳答案

注解处理器背后的意图是允许开发人员添加新类,而不是替换现有类。话虽如此,有一个错误允许您将代码添加到现有类。 Project Lombokleveraged这会将 getter 和 setter(除其他外)添加到已编译的 java 类中。

我用来“替换”方法/字段的方法是从输入类扩展或委托(delegate)给输入类。这允许您覆盖/转移对目标类的调用。

如果这是你的输入类:

InputImpl.java:

public class InputImpl implements Input{
public void foo(){
System.out.println("foo");
}
public void bar(){
System.out.println("bar");
}
}

您可以生成以下内容来“替换”它:

InputReplacementImpl.java:

public class InputReplacementImpl implements Input{

private Input delegate;

//setup delegate....

public void foo(){
System.out.println("foo replacement");
}
public void bar(){
delegate.bar();
}
}

这引出了一个问题,你如何引用 InputReplacementImpl 而不是 InputImpl。您可以生成更多代码来执行包装,也可以简单地调用预期生成代码的构造函数。

我不太确定你的问题是什么,但我希望这能对你的问题有所启发。

关于java - 使用注释处理器替换代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13690272/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com