我想知道构建某种java扩展或插件所需的一般步骤是什么。更具体地说,我希望在java中构建类似C ++结构的东西,这将允许我从特定类声明方法,以便我可以指示它们应该由JVM执行的顺序。现在这只是天空中的馅饼,我对AspectJ或其他java扩展的工作方式如何工作以允许您声明非Java原生的语法感兴趣。我假设这需要某种编译器插件。
作为一个例子,我设想了类似下面的内容
public struct weakProfile {
streamDataViaGprs();
sendSimpleMap();
}
public struct strongProfile {
streamDataVia3G();
sendComplexMap();
sendAudio();
}
在上面的例子中,如果我有一个Web服务并且客户端的配置文件很弱,这意味着他们用来调用服务的设备处理能力低,带宽能力差,那么我只想提供{ {1}}和streamDataViaGprs()
功能。但是,如果客户端设备具有强大的处理能力和出色的带宽连接,那么我希望sendSimpleMap()
,streamDataVia3G()
和sendComplexMap()
。这是我的最终目标,但是我不确定如上所述开发结构会涉及到什么,更不用说如果可能的话。
答案 0 :(得分:16)
没有编译器插件API。你可以做至少四件事:
1)为您的新语言编写自己的编译器,将您的代码转换为Java代码,然后将其提供给Java编译器(过去很流行,现在很少使用)。您的“编译器”实际上可能只进行简单的文本转换,将大部分代码保持不变,因此如果您的更改很小且本地化,这是一种合理的方法。
2)为您的新语言编写自己的编译器,该语言会发出Java .class文件(现在非常常见:Groovy,Scala,Clojure都以这种方式工作。)
3)使用“字节码工程库”来获取已编译的.class文件,分析它们,修改它们,然后将它们写回磁盘或动态加载并执行它们(这是AspectJ和大多数分析器所做的事情) 。)
4)获取Sun ^ H ^ H ^ HOracle的实际Java编译器的源代码 - 它在OpenJDK中可用 - 并对其进行修改。这是硬核,可能不是最好的计划。
您选择的路径当然取决于您的技能和要求。
答案 1 :(得分:3)
如果您使用的是Eclipse,可以查看Xtext。 它允许您在Eclipse中创建DSL和代码编辑器(具有语法突出显示和代码完成)。
还有JetBrains MPS元编程系统。
答案 2 :(得分:2)
看看JastAddJ。
答案 3 :(得分:1)
我建议看一下ObjectTeams。这是一个eclipse项目,允许增强其他封闭的源代码,如Eclipse的Java编译器,java文件的编辑器等。他们也构建了一些示例性的Java扩展。另一种选择是使用Jetbrains MPS,尽管这不是真正的Java。 MPS是可扩展语言的投影方法。它们带有Java表示和一堆很好的扩展。他们的“基础语言”可以被视为“Java ++”。
但是,我不熟悉C ++结构,但它不是一个普通的Java类,其公共字段与结构几乎相同?
答案 4 :(得分:1)
你真的应该进入一些Java annotations。它们允许您标记字段,类和方法,以便外部实体可以推断代码。烘焙到语言中的一个注释是@Override
,如果编译器看到这个注释,它会检查该方法实际上是否覆盖某些东西,否则它会抱怨。但是,您可以自由编写自己的注释,因此可以创建@struct
注释(尽管我认为自己并不是特别清楚......)。
注释被编译到类文件中,因此您可以使用普通的反射或一个更复杂的字节码操作库(ASM是最好的事情来推断代码)。
答案 5 :(得分:0)
感谢所有人的建议。我最终使用了Xtext,这让我可以构建自己的DSL(特定于域的语言)。非常好的工具!
答案 6 :(得分:0)
首先让我说我相信除了编译器插件之外,还有更简单的方法来解决你提到的问题。在我的脑海中,我将探索Java Enum类型的使用,这些类型是完整的对象并且可能包含行为。但是,Java Annotation Processing Tool可能是您完成编译时代码生成的一种方法。这是Project Lombok完成编译魔术的手段,因此探索它的代码可能很有用。