构建Java语言的扩展 - 步骤?

7
我想知道构建Java扩展或插件需要哪些一般步骤。更具体地说,我想在Java中构建类似于C++结构的东西,以便我可以声明特定类的方法,并指示JVM按照特定顺序执行它们。目前这只是一个空想,我对AspectJ或其他Java扩展如何工作以允许您声明非本机Java语法感兴趣。我假设这将需要某种编译器插件。
例如,我设想像下面这样的东西:
public struct weakProfile {
   streamDataViaGprs();
   sendSimpleMap();
}

public struct strongProfile {
   streamDataVia3G();
   sendComplexMap();
   sendAudio();
}

在上面的例子中,如果我有一个网络服务,而客户端具有较弱的配置文件,这意味着他们用来调用服务的设备处理能力低,带宽能力差,那么我只想提供 streamDataViaGprs()sendSimpleMap() 功能。然而,如果客户端设备具有强大的处理能力和出色的带宽连接,则我希望提供 streamDataVia3G(), sendComplexMap()sendAudio()。这是我的最终目标,但我不确定开发像上面那样的结构需要什么,更不用说它是否可能了。

2
JVM为什么要按照给定的顺序执行方法? - Thorbjørn Ravn Andersen
你能否更详细地阐述你想要做什么,例如提供一个示例并解释它的工作原理?也许有其他更简单的方法可以实现你想要的,而不是创建一些扩展Java语言的方式。 - Jesper
你好。我已经更新了我的原始帖子并阐明了我的想法。 - Joeblackdev
1
你所描述的不需要更改语言,听起来更像是使用“策略(Strategy)”模式(谷歌一下)。 - parsifal
1
你真正想要的是闭包。你想将一个简单的函数封装起来并像值一样处理它。像Clojure或Scala这样的JVM语言可以让你做到这一点。官方的“Java方式”是创建“策略”类,就像@parsifal建议的那样。 - John Cromartie
显示剩余2条评论
7个回答

16

没有编译器插件API。你至少可以做以下四件事情:

1)为你的新语言编写自己的编译器,将你的代码转换为Java代码,然后将其输入Java编译器(曾经很流行,现在很少使用)。你的“编译器”实际上可能只是进行简单的文本转换,大部分代码都不变,因此如果你的更改是小而局部的,这是一种合理的方法。

2)为你的新语言编写自己的编译器,它会发出Java .class文件(现在非常常见:Groovy、Scala、Clojure都是这样工作的)。

3)使用“字节码工程库”来获取已编译的.class文件,分析它们,修改它们,然后将它们写回磁盘或动态加载并执行它们(这是AspectJ和大多数性能分析器所做的事情)。

4)获取Sun^H^H^HOracle的Java编译器源代码——它在OpenJDK中可用——并修改它。这是强硬的做法,可能不是最好的计划。

当然,选择哪条路取决于你的技能和要求。


感谢你的提醒,Ernest。我的Java技能属于中级水平,以前从未做过这样的事情。对于我这样的技能水平,最好的方法是什么?我将使用Eclipse,并希望构建类似C++结构体的结构。因此,Eclipse不允许我编写这样的结构体而不抱怨。 - Joeblackdev
好的,让我们来看看。首先,什么是类似结构体?C++ 结构体与 C++ 类相同,只是成员默认为公共的。现在你可以创建类似于这样的 Java 类。请描述这些 Java 结构体的属性。 - Ernest Friedman-Hill
只是一种类似于类的定义,以便我可以指定我想要执行某些方法的顺序。使用C++结构体的想法只是类似于我想看到的。这只是一个粗略的概念。 - Joeblackdev
2
我对这个答案唯一的问题是,提问者并不真正想要或需要做他认为他需要做的事情... - John Cromartie
1
OP是函数指针吗?我不明白他想要什么,以及为什么需要改变Java。 - Tim Reynolds
@Tim Reynolds:当我第一次看到这个问题时,我的想法和你完全一样。“指向函数的指针!”然后,我想起了Java,“声明一个单一方法并由多个子类实现的接口!”然后我读了一下问题的评论,发现这基本上是策略设计模式。我不知道如何在C++结构中实现这个。 - 31eee384

3
如果您正在使用Eclipse,您可以查看Xtext。它允许您在Eclipse内创建DSL和代码编辑器(具有语法高亮和代码完成)。
还有JetBrains MPS,元编程系统。

是的,这就是我最终使用的。感谢提供信息。 - Joeblackdev

2

1

你真的应该学习一些Java注解。它们允许你标记字段、类和方法,以便外部实体可以推理代码。其中一个内置于语言中的注解是@Override,如果编译器看到这个注解,它会检查该方法是否确实覆盖了某些东西,否则就会报错。但是,你可以自由地编写自己的注解,因此你可以创建一个@struct注解(尽管我认为这不是特别清晰...)。

这些注解被编译到类文件中,因此你可以使用常规反射或更复杂的字节码操作库(ASM是最好的选择)来推理代码。


1

我建议看一下ObjectTeams。这是一个Eclipse项目,允许增强否则关闭源代码的功能,如Eclipse的Java编译器、Java文件编辑器等。他们还构建了一些示例Java扩展。另一个选择是使用Jetbrains MPS,虽然它不是实际的Java。MPS是一种可扩展语言的投影方法。它们提供了Java表示和一堆不错的扩展。他们的“基础语言”可以被视为类似于“Java ++”。

然而,我不熟悉C++结构体,但一个具有公共字段的普通Java类是否与结构体相同?


0

感谢大家提供的所有建议。最终我选择了使用Xtext,这使我能够构建自己的DSL(领域特定语言)。非常好用的工具!


-1

首先,我认为解决你提到的问题可能有比编译器插件更简单的方法。我会考虑使用Java 枚举类型,它们是完整的对象,可以包含行为。然而,Java 注解处理工具可能是实现编译时代码生成的一种方式。这就是Project Lombok实现其编译魔法的方式,因此探索其代码可能会有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接