Get minimize code to reproduce this
我有一个HelloWorldProcessor
,他只会生成源文件HelloWorldMessage.java
public interface HelloWorldMessage {
String HELLO_WORLD = "Hello World";
}
现在,我在代码中使用生成的值:
public class UseHelloWorld {
@Anno(HelloWorldMessage.HELLO_WORLD)
public void func(){
}
}
那很好。
但是,如果我将该值声明为常量并间接使用它,则会导致编译错误。
public class UseHelloWorld{
public static final String HW = HelloWorldMessage.HELLO_WORLD;
@Anno(UseHelloWorld.HW)
public void func(){
}
}
Javac给出symbol not found
错误:
UseHelloWorld.java:2: error: cannot find symbol
public static final String HW = HelloWorldMessage.HELLO_WORLD;
^
symbol: variable HelloWorldMessage
location: class UseHelloWorld
UseHelloWorld.java:4: error: element value must be a constant expression
@Anno(UseHelloWorld.HW)
^
2 errors
为什么我说“ javac”是因为它在ECJ和m2e-apt的eclipse中工作正常。
这是javac错误吗?如果没有,我该如何正确地间接使用生成的源?
答案 0 :(得分:2)
我不知道这个主题,所以尝试尝试一点。
按照您提供的步骤,您的示例似乎不适用于javac
,我认为不会调用处理器。您可以尝试使用一些调试参数来验证它:
-XprintProcessorInfo
:显示有关要求处理器处理哪些注释的信息-XprintRounds
:打印有关初始和后续注释处理回合的信息。-verbose
:详细的输出。这包括有关装入的每个类和编译的每个源文件的信息。第二,似乎您需要将处理器提供为jar,其中包含/META-INF/services/javax.annotation.processing.Processor
。我已经尝试过了,这更好,但仍然失败了,我认为这是因为源文件未编译,所以编译器无法检索有关注释的任何信息(我认为可以通过扫描源文件来实现)。
最后,我通过将注释的使用从UseHelloWorld
移到package-info.java
文件(或任何其他可编译的文件)来使其工作。现在,编译器可以看到该注释已在源文件中使用,并且调用了处理器来生成HelloWorldMessage
类,该类将在下一轮中进行编译。类UseHelloWorld
也会编译。
注意:我已经在文件中添加了import
和package
,否则即使存在HelloWorldMessage
类也无法编译。
我认为它在Eclipse中起作用的原因是因为使用了不同的工具来进行处理。或者,也许您已经生成了源文件一段时间,却忘了清理它。希望有人能提供更好的答案,我只是在分享我的实验。
更新
我很愚蠢地说我们应该将处理器作为jar提供,显然一个类文件就足够了(我可能使用了错误的类路径)。我对更新后的文章的猜测是,编译器无法处理所有情况。
在Eclipse中,我们看到了两个与@Anno
@Anno(HelloWorldMessage.HELLO_WORLD)
:HelloWorldMessage无法解析为变量@Anno(UseHelloWorld.HW)
:注释属性Anno.value的值必须是一个常量表达式也许在第一种情况下,编译器足够聪明,可以猜测注释处理器可以生成未知类型,因此可以尝试一下,在第二种情况下,由于注释使用不当,编译器会对其进行处理。