有没有自动将Groovy转换为Java的方法?

32

我继承了大量的Groovy代码,但由于以下几个原因,我发现它很难维护:

  1. 经常很难确定变量的类型。
  2. 推论:很容易使用不同类型修改变量,而不知道它。
  3. 许多错误直到运行时才会被发现(如果您的单元测试没有涵盖几乎所有内容,这是令人恐惧的)。
  4. 参数类型基本上被忽略。
  5. 我正在使用的IDE(STS Pro)很有用,但远远落后于Java。例如,重构根本不可用。
  6. 有时会提供建议,有时则不会。

尽管我欣赏该语言的简洁性,但维护却很困难且麻烦。

我曾试图手动将一些部分转换为Java,但非常痛苦。您是否知道任何工具或插件可以帮助进行此转换?


我已经找到了一个部分解决方案:Groovy++。虽然它不能将Groovy转换为Java,但它提供了静态变量和快速执行(实际上与Java几乎相等),而不会失去简洁的语法。我的担忧1、2、3、4已经得到解决,但我还没有找到Eclipse的插件。请参见http://code.google.com/p/groovypptest/wiki/Welcome。 - luiscolorado
8个回答

33

IntelliJ IDEA 对Groovy代码的重构支持相当不错。 它还具有从Groovy -> Java的源代码级转换器。大多数情况下,它生成的代码无法编译,但它可能有助于您开始转换代码的过程。 Groovy代码:

class HelloWorld {
def name
def greet() { "Hello ${name}" }
int add(int a, int b) {
    return a+b;
}
}

转换后的Java代码:

public class HelloWorld {
public GString greet() {
    return "Hello " + String.valueOf(name);
}

public int add(int a, int b) {
    return a + b;
}

public Object getName() {
    return name;
}

public void setName(Object name) {
    this.name = name;
}

private Object name;
}

16
在打开一个Groovy文件后,选择“重构”->“转换为Java”。 - Bogdan Calmac

16

也许不是你想听到的答案,但我建议你将重点放在学习Groovy上,而不是试图将代码转换为Java。在Groovy中有很多事情,简单地翻译成Java可能会出现问题(比如闭包)。任何自动转换为Java的尝试都会使代码难以阅读和理解。

如果你不能被说服坚持使用Groovy,并且必须迁移到Java,那么最好的方法就是手动迁移。


仅供参考。OP提到的IDE(STS Pro)是SpringSource Tool Suite。它是基于Eclipse的Spring特定版本,内置GroovyEclipse插件,通常比普通Eclipse版本领先一些。 - Mikezx6r
谢谢提供信息。我在 Google 上快速搜索了 STS Pro,但没有找到任何相关内容。我会将我的回答中涉及到这部分的内容删除。 - dbyrne
2
你看,我觉得自己刚刚完成了一轮爱上语言、买书、尽可能学习等操作。然后,就像我说的,我再次确认了Groovy的问题:它们给了你很多自由度,所以编写混乱代码比不编写更容易。Java也允许您编写混乱的代码,但这更困难。即使您继承或制造了Java代码混乱,重构也要容易得多。Groovy有很棒的理念,但在类型方面极其薄弱。我期待着有一天学会Groovy++...听说它可以修复Groovy的问题(我们拭目以待)。 - luiscolorado
1
Groovy++并不是为了“修复”Groovy,因为它并没有出现问题,它本来就应该是动态类型的。 - Dónal
2
自从Java 8的lambda闭包出现后,对于Groovy来说已经不再是一个优势了。 - Torsten

7

Groovy和Java语言都可以编译成相同的字节码(Java平台字节码)。因此,只需 (a) 将您的 .groovy 文件编译为 .class 文件; (b) 使用类似 JDGUI 的反编译工具将 .class 文件反编译为 .java 文件。


3
我找到了一种替代方案,使用Groovy++。它几乎具备了Groovy的所有优点,但又拥有Java的性能和强类型特性。此外,它基于Groovy开发,因此似乎只需要添加一个jar文件,并在代码顶部添加"@Typed"注释即可。
此外,它还增加了新功能,如“GrUnit”,并允许混合动态和静态类型,这将有助于创建DSL。因此,它可以与现有的Groovy代码混合使用,并与Grails一起使用。
该项目似乎还很年轻,但非常有前途。我已经开始尝试,并测试其可行性。
因此,这个答案实际上并没有说如何将Groovy转换为Java,但你可以得到更好的东西:两个世界的优点以及第三个可选世界--无意冒犯 :-) -- 静态类型和性能。

3

我的最佳建议是编写大量的单元测试

对于大多数动态语言来说,这个建议都是适用的,因为编译器提供的静态类型检查不够强大。您需要添加测试来检查输入和输出值是否具有正确的类型等。

我认为这将解决您大部分的问题。


这正是关键所在:动态语言的解决方案是创建更大的单元测试。因此,一方面,您可以节省在Groovy编码的时间,但另一方面,您必须在单元测试中编写更多代码。这在某种程度上至少部分地削弱了任何动态语言的优势。 - luiscolorado
你的决定,但我认为更多的测试从来不会是坏事...... 如果你聪明的话,你可以编写既能够提供功能覆盖率又能够测试动态类型假设的测试。 - mikera
7
我非常支持单元测试。让我解释一下:如果每次我创建一个方法时都必须创建一个新的单元测试来检查该方法是否返回正确的类型,那么就有些不对劲了。如果我必须在每个方法中手动检查传入变量的类型,那这样写出来的代码就不够清晰易读。我们不应该做编译器应该做的工作。 - luiscolorado

0

我们需要将大约1000个Groovy类转换为Java 8。

  • 自动化:我认为结合手动步骤是可能的

迁移的可能步骤:

  • def变量:在IDE中手动替换为正确的类名

  • def方法:在IDE中手动替换为正确的类名作为返回值

  • 文件重命名:自动将所有.groovy文件替换为.java文件(Java 8)

  • 闭包:在IDE中手动替换为Java 8的Lambda表达式和Java 8的流

  • Groovy重写方法:在IDE中手动替换为较新的Java jdk类,例如新的文件io、新的日期API或包含Apache库

使用单元测试来控制重构过程。

附注:我们使用带有Groovy插件的Eclipse。

祝好,Roebi


0

对于有类似问题的人,你可以看一下GMavenPlus


0

一年前有些问题。在经历了一个月或两个月的Groovy狂热之后,它在现实世界中变得脆弱。即使是GReclipse 2.0也无法减轻痛苦,代码变得难以管理和痛苦。 简短回答你的问题 - 没有真正好的工具来做这件事。我用Spring JdbcTemplate替换了GSql,用回调函数替换了闭包。所有这些都需要手动决定替换策略,所以如果你想得到良好的代码,你需要手动进行。否则,你可以使用一些Java反编译器,但我认为这不是你真正想要的。


7
尽管我不太喜欢动态语言,但我不同意"代码会变得难以管理和痛苦"这种一般性的说法。只有当某人使它难以管理和痛苦时,代码才会变得难以管理和痛苦。 - R. Martinho Fernandes
2
@Martinho Fernandes,这是您的观点,我尊重它。但认为“语言无所谓,所有问题都是程序员的问题”是错误的。 - Alexey Sviridov
1
你能感受到我的痛苦。我确实不得不处理许多难以管理的代码。我已经看到这些争论很多次,涉及各种编程语言。一方说:“是啊,我的语言'X'可以做你的语言'Y'所能做的一切。”虽然原则上可能是真的,但是那种语言X更慢,更难维护,或者更容易搞砸事情。当你继承了一堆混乱的Groovy代码时,你会希望他们使用Java。在Java中也可以搞砸事情,只是更难而已。 - luiscolorado

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